Code Reference

infer keyword

TypeScript · Reference cheat sheet

infer keyword

TypeScript · Reference cheat sheet


📋 Overview

infer introduces a type variable inside a conditional type’s extends clause. Use it to extract return types, element types, promise payloads, and pattern pieces from other types — the foundation of many utility types.

🔧 Core concepts

  • FormT extends … infer U … ? True : False.
  • ScopeU is only usable in the true branch.
  • Multiple infer — can appear several times; each binds independently.
  • Variance — position (covariant/contravariant) affects inference direction.
  • Distributive — bare type params distribute over unions in conditionals.

💡 Examples

type ReturnOf<T> = T extends (...args: any) => infer R ? R : never;
type R = ReturnOf<() => Promise<number>>; // Promise<number>

type Awaited<T> = T extends PromiseLike<infer U> ? Awaited<U> : T;
type A = Awaited<Promise<Promise<string>>>; // string

type Head<T> = T extends [infer H, ...unknown[]] ? H : never;
type H = Head<[1, 2, 3]>; // 1

type Elem<T> = T extends (infer E)[] ? E : never;
type E = Elem<string[]>; // string

type PropType<T, K extends PropertyKey> =
  T extends { [P in K]: infer V } ? V : never;

// Template + infer
type StripPrefix<S> = S extends `id-${infer Rest}` ? Rest : S;
type X = StripPrefix<"id-42">; // "42"

// Contravariant infer in parameters (simplified)
type FirstArg<T> = T extends (arg: infer A, ...rest: any) => any ? A : never;
// Built-ins (prefer these): ReturnType, Parameters, Awaited, InstanceType
type RT = ReturnType<() => boolean>;
type P = Parameters<(a: string, b: number) => void>; // [string, number]

⚠️ Pitfalls

  • infer only works in conditional extends clauses, not arbitrary positions.
  • Distributive conditionals: wrap as [T] extends […] to disable distribution.
  • Over-broad any in patterns weakens inference.
  • Recursive infer / conditionals can hit instantiation depth limits.
  • Prefer stdlib utilities when they already exist (ReturnType, etc.).

On this page