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

# Kotlin Type Projection

Type projection in Kotlin is a use-site variance mechanism that restricts the type signature of a generic class or interface at the point of its usage. By applying variance modifiers (`in` or `out`) or the star projection (`*`) to type arguments in variable declarations or function parameters, developers can safely accept generic types with differing type parameters, effectively overriding the generic type's default invariance.

Unlike declaration-site variance (where modifiers are applied to the class definition itself, e.g., `class Box<out T>`), type projection occurs where the type is instantiated or referenced.

## Covariant Projection (`out`)

Applying the `out` modifier at the use-site creates a covariant projection. It restricts the generic object to act strictly as a **producer**.

* **Mechanics:** The compiler allows calling methods that return the generic type `T`, but prohibits calling any methods that take `T` as a parameter.
* **Type Safety:** It guarantees that the object will only emit instances of `T` (or its subtypes) and prevents the injection of incompatible types.

```kotlin theme={"dark"}
class MutableReference<T>(var value: T)

// The parameter is projected covariantly
fun readOnly(ref: MutableReference<out Number>) {
    val n: Number = ref.value // ALLOWED: Reading is safe
    // ref.value = 42         // ERROR: Setter expects 'Nothing', cannot write
}
```

## Contravariant Projection (`in`)

Applying the `in` modifier at the use-site creates a contravariant projection. It restricts the generic object to act strictly as a **consumer**.

* **Mechanics:** The compiler allows calling methods that take the generic type `T` as a parameter, but restricts the type returned when reading from the object.
* **Type Safety:** It guarantees that the object can safely consume instances of `T` (or its subtypes). Because the exact type argument passed to the generic class is unknown at the use-site, the compiler cannot safely return `T`. Instead, reading from an `in`-projected type returns the declared **upper bound** of the generic type parameter. If no explicit upper bound is defined at the declaration site, it defaults to `Any?`.

```kotlin theme={"dark"}
class BoundedReference<T : Number>(var value: T)

// The parameters are projected contravariantly
fun writeOnly(ref: MutableReference<in Number>, boundedRef: BoundedReference<in Int>) {
    ref.value = 42             // ALLOWED: Writing is safe
    boundedRef.value = 10      // ALLOWED: Writing is safe
    
    // Reading returns the declaration-site upper bound, not the exact type argument
    val a: Any? = ref.value          // ALLOWED: Upper bound of MutableReference<T> is Any?
    val b: Number = boundedRef.value // ALLOWED: Upper bound of BoundedReference<T : Number> is Number
    
    // val n: Number = ref.value     // ERROR: Returns 'Any?', not 'Number'
    // val i: Int = boundedRef.value // ERROR: Returns 'Number', not 'Int'
}
```

## Star Projection (`*`)

Star projection is used when the exact type argument is unknown or irrelevant, but type safety must still be maintained. It provides a safe approximation of the generic type based on its declaration.

* **Mechanics:**
  * For reading (producing), `Foo<*>` acts like `Foo<out TUpper>`, where `TUpper` is the upper bound of the generic parameter (defaults to `Any?`).
  * For writing (consuming), `Foo<*>` acts like `Foo<in Nothing>`, meaning you cannot write any value to it.
* **Type Safety:** It prevents unsafe writes entirely while allowing safe, generalized reads.

```kotlin theme={"dark"}
// The parameter uses star projection
fun inspect(ref: MutableReference<*>) {
    val a: Any? = ref.value    // ALLOWED: Reads as 'out Any?'
    // ref.value = "String"    // ERROR: Writes as 'in Nothing'
}
```

## Type Projection vs. Invariance

By default, generic types in Kotlin are invariant. Type projection explicitly narrows the capabilities of the type to achieve subtyping flexibility.

```kotlin theme={"dark"}
// Invariant usage (No projection)
fun process(ref: MutableReference<Number>) {
    val n: Number = ref.value  // ALLOWED
    ref.value = 42             // ALLOWED
}

val intRef = MutableReference<Int>(10)

// process(intRef)             // ERROR: MutableReference<Int> is not MutableReference<Number>
// readOnly(intRef)            // ALLOWED: MutableReference<Int> is a subtype of MutableReference<out Number>
```

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