Skip to content
masterclassBuddyTech Buzz5 fresh blogs · 5:00 AM IST

TypeScript · Function

Conditional Types

Conditional types choose one of two types by testing whether one type is assignable to another. They can map generic inputs to precise outputs, distribute over unions, and infer types from matched structures.

Since
TypeScript 2.8

How it works

A conditional type tests assignability with extends and chooses one of two types. If the checked type is assignable to the tested type, TypeScript selects the true branch; otherwise it selects the false branch. When generic information is insufficient, evaluation can be deferred, and a naked type parameter distributes the condition across union members.

Syntax

T extends U ? X : Y

Parameters

NameTypeDescription
TtypeThe type being tested against the condition.
UtypeThe type relationship target used by extends.
XtypeThe type selected when T is assignable to U.
YtypeThe type selected when T is not assignable to U.

Returns

The conditional type resolves to either the true branch type or the false branch type, or remains deferred until enough type information is available.

Key points

  • They model input-dependent results, allowing a type-level API to select an output type from the input type.
  • The syntax resembles a JavaScript ternary, but it operates on type relationships rather than runtime values.
  • Assignability determines the selected branch: the true type is chosen when the condition succeeds, and the false type otherwise.
  • The successful branch provides additional constraints for generic types, enabling more precise type-level transformations.
  • infer captures a type discovered while matching the checked type against a structural pattern.

Common mistakes

  • A conditional type whose checked type is a naked type parameter distributes over each member of a union. Wrap both sides in tuple types, such as [T] extends [U], when you need to test the union as a whole.

Example: Select a result type from an input type

type IdLabel = { id: number };
type NameLabel = { name: string };

type Label<T extends number | string> =
  T extends number ? IdLabel : NameLabel;

function createLabel<T extends number | string>(value: T): Label<T> {
  return (typeof value === "number"
    ? { id: value }
    : { name: value }) as Label<T>;
}

const byId = createLabel(42);
const byName = createLabel("Ada");

The type-level condition selects the result shape from the argument type, while the runtime branch constructs the corresponding value.

When to use it

Input-dependent API results

A function's return shape changes according to whether its generic input is a string or number.

Filtering union members

A type transformation should retain only union members matching a structural or primitive constraint.

Type extraction

A utility type needs to extract a return type, tuple element, or other component from a matched type pattern.

Recursive type transformations

A deeply nested type must be unwrapped or transformed recursively.

Interview questions

QWhat is a conditional type, and when does it choose each branch?

A conditional type has the form T extends U ? X : Y. It resolves to X when T is assignable to U, and to Y otherwise; if generic information is not sufficient, evaluation is deferred.

Follow-up: How can a conditional type process a union? A distributive conditional type applies the test independently to each member when the checked type is a naked type parameter.

QWhy can conditional types simplify function overloads?

Conditional types let a generic API express different output types for different input types. For example, a number input can map to an ID-shaped result while a string input maps to a name-shaped result, reducing overloads.

Follow-up: What limitation remains in the function body? The implementation must still satisfy runtime checking; the conditional return type does not itself execute or validate JavaScript behavior.

QWhat does infer do inside a conditional type?

infer introduces a type variable inside the extends pattern so TypeScript can extract part of a matching type. A common use is inferring a function's return type or an element from a tuple.

Follow-up: How can recursive type transformations use this feature? A conditional type can refer to itself in its branches to recursively unwrap or transform nested structures.

  • infer
  • Distributive conditional types
  • Utility Types
  • TypeScript 2.8
  • Recursive Conditional Types

Source: TypeScript: Documentation - Conditional Types. Checked 2026-10-15.