Skip to content
webtype.orgConditional types

    ↑↓ move · ⏎ open · esc close

    Constructs

    Conditional types

    The type-level `if`. The question it asks is always assignability.

    What it is

    Not equality, not instance-of — assignability, in one direction. And when the checked type is a bare type parameter, the conditional distributes: it runs once per union member and the results are unioned back. That single behaviour explains most of what looks like magic in the standard library, and most of what looks like a bug in your own types.

    Examples

    • IsString<'hello'>
      true
    • IsString<string | number>
      boolean

      It distributed: `true` for `string`, `false` for `number`, unioned back into `boolean`. Surprising until you know, obvious afterwards.

    • NoDistribute<string | number>
      false

      The tuple wrapper turns distribution off, and now the union is judged as one thing.

    Each resolved type above was printed by TypeScript 5.9.3, not written by hand.

    What it does not do

    • It does not test equality. `T extends string` is true for every string literal too, and asking "are these the same type" needs the two-conditional identity trick, not this.
    • It does not distribute when the checked type is anything but a bare parameter. Wrapping either side — in a tuple, an object, anything — switches it off.

    Takeaway

    When a conditional gives an answer you did not expect, ask first whether it distributed. `[T] extends [U]` is the switch, and it is the fix about half the time.