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

# TypeScript Variance Annotation

Variance annotations in TypeScript are explicit modifiers applied to generic type parameters to declare how the subtyping relationship of the generic type relates to the subtyping relationship of its type arguments. By using the `in` and `out` keywords, developers can explicitly define a type parameter as contravariant, covariant, or invariant, bypassing the compiler's default structural variance inference.

## Syntax

Variance annotations are placed directly before the type parameter in a generic declaration:

```typescript theme={"dark"}
type Covariant<out T> = { /* ... */ };
type Contravariant<in T> = { /* ... */ };
type Invariant<in out T> = { /* ... */ };
```

## Variance Mechanics

To understand the annotations, consider two types, `Sub` and `Super`, where `Sub` is a subtype of `Super` (e.g., `Sub` is assignable to `Super`).

### Covariance (`out`)

The `out` modifier declares that the generic type's subtyping direction matches the type parameter's subtyping direction. It indicates that the type parameter is strictly produced (emitted) by the type.

* **Rule:** If `Sub` extends `Super`, then `Generic<Sub>` is assignable to `Generic<Super>`.
* **Enforcement:** The compiler will throw an error if an `out` type parameter appears in a contravariant position (e.g., as a method argument).

### Contravariance (`in`)

The `in` modifier declares that the generic type's subtyping direction is the exact reverse of the type parameter's subtyping direction. It indicates that the type parameter is strictly consumed (received) by the type.

* **Rule:** If `Sub` extends `Super`, then `Generic<Super>` is assignable to `Generic<Sub>`.
* **Enforcement:** The compiler will throw an error if an `in` type parameter appears in a covariant position (e.g., as a return type).

### Invariance (`in out`)

Applying both modifiers declares that the generic type requires strict equality of the type parameter. Subtyping is rejected in both directions. It indicates the type parameter is both consumed and produced.

* **Rule:** `Generic<Sub>` and `Generic<Super>` are mutually unassignable. Exact type matching is required.

## Structural Visualization

The following code demonstrates the mechanical assignment rules enforced by variance annotations:

```typescript theme={"dark"}
type Super = { a: string };
type Sub = { a: string; b: number };

// 1. Covariance (out)
type Producer<out T> = { produce: () => T };

declare let produceSub: Producer<Sub>;
declare let produceSuper: Producer<Super>;

produceSuper = produceSub; // Valid: Producer<Sub> is a subtype of Producer<Super>
// produceSub = produceSuper; // Error


// 2. Contravariance (in)
type Consumer<in T> = { consume: (arg: T) => void };

declare let consumeSub: Consumer<Sub>;
declare let consumeSuper: Consumer<Super>;

consumeSub = consumeSuper; // Valid: Consumer<Super> is a subtype of Consumer<Sub>
// consumeSuper = consumeSub; // Error


// 3. Invariance (in out)
type Processor<in out T> = { process: (arg: T) => T };

declare let processSub: Processor<Sub>;
declare let processSuper: Processor<Super>;

// processSuper = processSub; // Error
// processSub = processSuper; // Error
```

## Compiler Validation

When a variance annotation is applied, TypeScript statically verifies that the internal structure of the type adheres to the declared variance contract.

```typescript theme={"dark"}
// ERROR: Type 'T' is declared 'out' but occurs in an 'in' position.
type InvalidProducer<out T> = {
    produce: () => T;
    consume: (arg: T) => void; 
};

// ERROR: Type 'T' is declared 'in' but occurs in an 'out' position.
type InvalidConsumer<in T> = {
    consume: (arg: T) => void;
    produce: () => T;
};
```

By explicitly declaring variance, the TypeScript compiler skips the deep structural comparison it normally performs to infer variance, relying instead on the declared contract. This reduces the computational cost of type checking in deeply nested or highly complex generic structures.

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