Conditional Types

Presentation Scope

  • Awareness about the more advanced language features
  • Offer an intuition about conditional types
  • Extract the return type of a function

Conditional types

  • Introduced in TypeScript 2.8
  • They work on type variables (generics)
  • Used to express more complex JavaScript constructs

CT general form

General form

T extends U ? X : Y

Selects one of the 2 types: X or Y

Evaluation of the conditional type expression:

  • it resolves immediately to one of the 2 possible types
  • it defers when the condition depends on other type variables

CT properties

Distributivity

// Remove types from T that are assignable to U
type Diff<T, U> = T extends U ? never : T;

type TheDiffResult = Diff<"a" | "b" | "c" | "d", "a" | "c" | "f">; // "b" | "d"
T extends U ? X : Y;

// When T = A | B | C it resolves to
(A extends U ? X : Y) | (B extends U ? X : Y) | (C extends U ? X : Y);

Example:

CT properties

Non recursive

Just like union and intersection types

type ElementType<T> = T extends any[] ? ElementType<T[number]> : T; // Error

Not true anymore starting with TypeScript 4.1

infer declarations

  • They define a new type variable
  • Can be used only on the true branch of the CT

Extract function return type

Is not possible to use infer outside of CT

// This is not supported
type SomeType<T extends (...args: any[]) => infer R> = R;

Extracting the return type of a function

type AnyFunction = (...args: any[]) => any;

type ReturnType<T extends AnyFunction> 
   = T extends (...args: any[]) => infer R ? R : any;

TypeScript already comes with a default type

ReturnType<T>

Predefined CTs

TypeScript ships with some predefined CT

Exclude<T, U> — Exclude from T those types that are assignable to U.
Extract<T, U> — Extract from T those types that are assignable to U.
NonNullable<T> — Exclude null and undefined from T.
ReturnType<T> — Obtain the return type of a function type.
InstanceType<T> — Obtain the instance type of a constructor function type.
Made with Slides.com