Conditional Types

Types that branch — choosing one type or another based on a compile-time relationship.

A conditional type is an if/else for types: T extends U ? X : Y. If T is assignable to U, the type resolves to X, otherwise Y.

type IsString<T> = T extends string ? "yes" : "no";
type A = IsString<"hi">; // "yes"
type B = IsString<42>;   // "no"

Distribution over unions

When the checked type is a naked type parameter and you feed it a union, the condition distributes over each member. ToArray<string | number> becomes string[] | number[], not (string | number)[]. Wrap both sides in a one-tuple — [T] extends [U] — to switch distribution off when you want the union treated as a whole.

Conditional types are how utility types like Exclude, Extract, and NonNullable are built.

Example

Try it yourself
Loading editor…
Press Run to execute the code.

When to use it

  • A utility type extracts the element type from an array type using a conditional to unwrap T[].
  • A library conditional type converts a sync function type to an async one by inspecting the return type.
  • A form helper uses conditional types to make only the fields matching a specific value type required.

More examples

Basic conditional type

A conditional type evaluates T extends string at compile time and selects true or false as the resulting type.

Example · ts
type IsString<T> = T extends string ? true : false;

type A = IsString<string>;  // true
type B = IsString<number>;  // false
type C = IsString<'hello'>; // true (literal extends string)

Unwrap array element type

Uses infer to capture the element type E from an array type, returning never when T is not an array.

Example · ts
type ElementType<T> = T extends (infer E)[] ? E : never;

type A = ElementType<string[]>;   // string
type B = ElementType<number[]>;   // number
type C = ElementType<boolean>;    // never (not an array)

Distributive conditional type

When T is a union, the conditional distributes over each member, filtering out null and undefined to produce a clean type.

Example · ts
type NonNullable<T> = T extends null | undefined ? never : T;

type A = NonNullable<string | null | undefined>; // string
type B = NonNullable<number | null>;             // number

Discussion

  • Be the first to comment on this lesson.
Conditional Types — TypeScript | SoundsCode