> ## Documentation Index
> Fetch the complete documentation index at: https://docs.syntblaze.com/llms.txt
> Use this file to discover all available pages before exploring further.

# Dart Extension

Dart extensions (formally "extension methods") provide a mechanism to inject new functionality into existing types without modifying their underlying source code, subclassing, or implementing wrapper classes. They operate via static dispatch, meaning the extension member invoked is determined strictly by the static type of the receiver variable at compile time, rather than its runtime type.

## Syntax

The declaration utilizes the `extension` and `on` keywords to bind a named or unnamed extension block to a specific target type.

```dart theme={"dark"}
extension ExtensionName on TargetType {
  // Member declarations
}
```

## Member Constraints

Extensions can encapsulate several types of members, but they are strictly stateless regarding the target instance.

**Allowed Members:**

* Instance methods
* Getters and setters
* Operators
* Static fields and static methods (accessed via `ExtensionName.staticMember`)

**Disallowed Members:**

* Instance variables (extensions cannot declare state)
* Constructors

## Static Resolution Mechanics

Because extensions are resolved statically, they cannot be invoked on variables typed as `dynamic`. The Dart analyzer must know the exact type at compile time to bind the extension.

```dart theme={"dark"}
extension StringExt on String {
  int get charCount => length;
}

void main() {
  String staticString = "Dart";
  print(staticString.charCount); // Valid: Statically resolved

  dynamic dynamicString = "Dart";
  print(dynamicString.charCount); // NoSuchMethodError: Extensions do not work with dynamic
}
```

If a target class already implements a member with the same **name** as an extension member, the class's instance member always takes precedence. Dart does not support method overloading; therefore, method resolution is based strictly on the member's name, not its signature. If a name collision occurs, the extension member is ignored entirely, even if the class member and extension member have completely different signatures.

## Extensions on Nullable Types

Extensions can be explicitly declared on nullable types by appending `?` to the target type. This is a unique feature that allows extension members to be invoked safely on potentially null variables without requiring null-aware operators (`?.`). Inside the extension block, the `this` reference can be null, meaning the extension must handle nullability internally.

```dart theme={"dark"}
extension NullableStringExt on String? {
  bool get isNullOrEmpty => this == null || this!.isEmpty;
}

void main() {
  String? text;
  // Invoked directly on a null variable without '?.'
  print(text.isNullOrEmpty); // Valid: Prints 'true'
}
```

## Generic Extensions

Extensions fully support generics, allowing you to apply type parameters to the extension itself, which are then passed down to the target type.

```dart theme={"dark"}
extension GenericQueue<T> on List<T> {
  T? get peek => isEmpty ? null : first;
}
```

You can also apply type bounds to restrict the extension to specific generic implementations:

```dart theme={"dark"}
// Only applies to Lists containing numeric types
extension MathOperations<T extends num> on List<T> {
  double get sum => fold(0, (total, current) => total + current);
}
```

## Unnamed Extensions

If an extension does not require explicit referencing (e.g., for conflict resolution), the name can be omitted. Unnamed extensions are inherently private to the library (file) in which they are declared and cannot be imported into other files.

```dart theme={"dark"}
extension on int {
  int get doubled => this * 2;
}
```

## Conflict Resolution

When multiple extensions in the same scope declare members with identical names for the same target type, a static conflict occurs. Dart provides two mechanisms to resolve this:

**1. Import Visibility**
Restrict the imported extensions using `show` or `hide` directives.

```dart theme={"dark"}
import 'extension_a.dart' show StringExtA;
import 'extension_b.dart' hide StringExtB;
```

**2. Explicit Extension Application**
Bypass the implicit receiver syntax and invoke the extension explicitly by wrapping the target instance. This treats the extension name similarly to a wrapper class, though it remains a zero-cost abstraction at runtime.

```dart theme={"dark"}
extension ExtA on String {
  void process() => print('A');
}

extension ExtB on String {
  void process() => print('B');
}

void main() {
  String text = "Dart";
  
  // text.process(); // Compile-time error: Ambiguous extension
  
  ExtA(text).process(); // Explicitly invokes ExtA's process
  ExtB(text).process(); // Explicitly invokes ExtB's process
}
```

<div
  style={{ 
display: "flex", 
justifyContent: "space-between", 
alignItems: "center", 
maxWidth: "754px", 
padding: "1rem 0",
marginBottom: "24px"
}}
>
  <span style={{ fontWeight: "bold", fontSize: "1.25rem", color: "var(--tw-prose-headings)", fontFamily: "Inter, ui-sans-serif, system-ui, sans-serif" }}>Tired of Poor Dart Skills? Fix That With Deep Grasping!</span>

  <a
    href="https://syntblaze.com"
    target="_blank"
    style={{ 
  marginLeft: "24px",
  textDecoration: "none", 
  backgroundColor: "#007AFF",
  color: "#ffffff", 
  padding: "6px 16px", 
  borderRadius: "16px",
  fontSize: "0.9rem",
  fontWeight: "600",
  textAlign: "center",
  transition: "background-color 0.2s ease"
}}
  >
    Learn More
  </a>
</div>

<div style={{ display: "flex", gap: "12px", flexWrap: "wrap" }}>
  <img src="https://mintcdn.com/syntblazellc/-L0ums_2lctDSZ1l/images/skill-tracking.png?fit=max&auto=format&n=-L0ums_2lctDSZ1l&q=85&s=b9b0305c93bb501c9e767b5c76c88835" style={{ width: "30%", minWidth: 60 }} width="621" height="1344" data-path="images/skill-tracking.png" />

  <img src="https://mintcdn.com/syntblazellc/23tyuOzaWS88qFlc/images/nuggets.png?fit=max&auto=format&n=23tyuOzaWS88qFlc&q=85&s=c86c80197299762989e9b882419b2109" style={{ width: "30%", minWidth: 60 }} width="621" height="1344" data-path="images/nuggets.png" />

  <img src="https://mintcdn.com/syntblazellc/-L0ums_2lctDSZ1l/images/bite-sized-exercises.png?fit=max&auto=format&n=-L0ums_2lctDSZ1l&q=85&s=a65f9a38c37ff28ab73ed783c53c60e3" style={{ width: "30%", minWidth: 60 }} width="621" height="1344" data-path="images/bite-sized-exercises.png" />
</div>

<div style={{ display: "flex", gap: "12px", flexWrap: "wrap", marginTop: "12px" }}>
  <img src="https://mintcdn.com/syntblazellc/-L0ums_2lctDSZ1l/images/mastery-chain.png?fit=max&auto=format&n=-L0ums_2lctDSZ1l&q=85&s=748a1763454713e679260fbb95f154a2" style={{ width: "30%", minWidth: 60 }} width="621" height="1344" data-path="images/mastery-chain.png" />

  <img src="https://mintcdn.com/syntblazellc/-L0ums_2lctDSZ1l/images/element-previews.png?fit=max&auto=format&n=-L0ums_2lctDSZ1l&q=85&s=242f61448ff5dd6deaaab2dccc13b507" style={{ width: "30%", minWidth: 60 }} width="621" height="1344" data-path="images/element-previews.png" />

  <img src="https://mintcdn.com/syntblazellc/-L0ums_2lctDSZ1l/images/element-explanations.png?fit=max&auto=format&n=-L0ums_2lctDSZ1l&q=85&s=cf0fc1c31f9cd0fc26716781be05fbc9" style={{ width: "30%", minWidth: 60 }} width="621" height="1344" data-path="images/element-explanations.png" />
</div>
