thecodex.expert · The Codex Family of Knowledge
TypeScript

Conditional Types

infer lets a conditional type reach INTO another type—like pulling a function’s return type back out—entirely at the type level, with zero runtime code.

TypeScript 6.0 T extends U ? X : Y Last verified:
Canonical Definition

A conditional type has the form T extends U ? X : Y: if T is assignable to U, the result is X; otherwise Y — the type-level equivalent of a ternary expression. The infer keyword, used inside the extends clause, captures part of the matched type as a new named type variable usable in the result, which is how TypeScript's own built-in utility types like ReturnType<T> extract a function's return type without ever running any code.

A basic conditional type

This is evaluated entirely at compile time, purely on types — no runtime check, no generated code for the condition itself.

TypeScriptbasic_conditional.ts
type IsString<T> = T extends string ? "yes" : "no";

type A = IsString<string>;    // "yes"
type B = IsString<number>;    // "no"

infer: extracting a type from within the condition

Rather than just returning a fixed X or Y, infer lets the result reuse a piece captured FROM the matched type itself — this exact pattern is how TypeScript's own ReturnType<T> is implemented.

TypeScriptinfer_keyword.ts
type MyReturnType<T> = T extends (...args: any[]) => infer R ? R : never;

function getUser() {
    return { name: "Alice", age: 30 };
}

type UserResult = MyReturnType<typeof getUser>;
// { name: string; age: number } — extracted, without calling getUser at all

Distributive conditional types over a union

When T in T extends U ? X : Y is a "naked" type parameter and the actual argument is a union, TypeScript applies the conditional to EACH member of the union separately and unions the results — a subtle but genuinely useful behavior, since it's how filtering a union by type works.

TypeScriptdistributive.ts
type ExcludeString<T> = T extends string ? never : T;

type Result = ExcludeString<string | number | boolean>;
// distributes over each member: never | number | boolean
// simplifies to: number | boolean

Sources

1
Microsoft. TypeScript Handbook, "Conditional Types", typescriptlang.org/docs/handbook/2/conditional-types.html.