> ## 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 Type Parameter Bound

A type parameter bound restricts the set of concrete types that can be substituted for a generic type parameter. By applying a bound, the Dart type system guarantees that any type argument provided at compile time is a subtype of the specified bounding type. This allows the compiler to safely resolve method and property lookups on instances of the generic type against the interface of the bound.

In Dart, type bounds are declared using the `extends` keyword within the angle brackets `< >` of a generic class, mixin, interface, or method declaration.

```dart theme={"dark"}
class GenericDeclaration<T extends BoundingType> {
  // Implementation
}
```

## Subtyping Rules and Compiler Behavior

When a bound is established as `<T extends BoundingType>`, any type argument `X` supplied during instantiation must satisfy the subtyping relationship `X <: BoundingType`. If `X` is not a subtype of `BoundingType`, the Dart analyzer emits a compile-time error.

Because the compiler enforces this constraint, instances of `T` within the generic scope are treated as instances of `BoundingType`.

```dart theme={"dark"}
class Base {
  void baseMethod() {}
}

class Derived extends Base {}

// T is constrained to Base or its subtypes
class Container<T extends Base> {
  final T instance;
  
  Container(this.instance);

  void invoke() {
    // The compiler allows this because T is guaranteed to extend Base
    instance.baseMethod(); 
  }
}

// Valid: Derived <: Base
Container<Derived> validContainer = Container(Derived());

// Invalid: String is not a subtype of Base
// Container<String> invalidContainer = Container("text"); // Compile-time error
```

## Implicit and Nullability Bounds

If a generic type parameter is declared without an explicit bound (e.g., `<T>`), Dart implicitly applies the top type `Object?` as the bound. This means the type parameter accepts any type, including nullable types.

To explicitly restrict a type parameter to non-nullable types, the bound must be set to the non-nullable `Object`.

```dart theme={"dark"}
// Implicitly <T extends Object?>
class Unbounded<T> {
  T? value; // T can be nullable (e.g., String?)
}

// Explicitly restricted to non-nullable types
class NonNullableBound<T extends Object> {
  T value; // T cannot be a nullable type (e.g., String? is invalid)
  
  NonNullableBound(this.value);
}
```

## F-Bounded Quantification (Recursive Bounds)

Dart supports F-bounded polymorphism, allowing a type parameter to appear within its own bound. This is strictly used when the bounding type is itself a generic type that requires the implementing type as an argument.

```dart theme={"dark"}
abstract class Equatable<T> {
  bool isEquivalent(T other);
}

// T is constrained by a generic interface parameterized over T itself
class Processor<T extends Equatable<T>> {
  bool compare(T a, T b) {
    return a.isEquivalent(b);
  }
}
```

## Multiple Bounds

Dart does not support intersection types for generic bounds (e.g., `<T extends TypeA & TypeB>`). A type parameter can only have a single explicit `extends` clause. To enforce multiple constraints, the bounding type itself must be a composite interface (an abstract class or mixin) that implements the required supertypes.

<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>
