🔷 TypeScript Q15 / 101

What are utility types?

AI-Powered Answer ✓ Answered

TypeScript utility types are powerful built-in type transformations that allow you to manipulate, modify, and construct new types based on existing ones. They help you write more robust, flexible, and maintainable code by reducing boilerplate and enforcing type safety in complex scenarios.

What are Utility Types?

At their core, utility types are generic types that take one or more types as arguments and return a new type. They are designed to simplify common type operations, such as making properties optional, extracting specific properties, or deriving types from function signatures. This makes TypeScript development more efficient and types easier to manage.

Common Utility Types

Partial<Type>

Constructs a type with all properties of Type set to optional. This utility will return a type that represents a subset of the properties of Type.

typescript
interface Todo {
  title: string;
  description: string;
  completed: boolean;
}

type PartialTodo = Partial<Todo>;
/*
Equivalent to:
interface PartialTodo {
  title?: string;
  description?: string;
  completed?: boolean;
}
*/

Readonly<Type>

Constructs a type with all properties of Type set to readonly, meaning the properties of the constructed type cannot be reassigned.

typescript
interface Todo {
  title: string;
}

type ReadonlyTodo = Readonly<Todo>;
/*
Equivalent to:
interface ReadonlyTodo {
  readonly title: string;
}
*/

Pick<Type, Keys>

Constructs a type by picking the set of properties Keys (a string literal or union of string literals) from Type.

typescript
interface Todo {
  title: string;
  description: string;
  completed: boolean;
}

type TodoPreview = Pick<Todo, 'title' | 'completed'>;
/*
Equivalent to:
interface TodoPreview {
  title: string;
  completed: boolean;
}
*/

Omit<Type, Keys>

Constructs a type by picking all properties from Type and then removing Keys (a string literal or union of string literals).

typescript
interface Todo {
  title: string;
  description: string;
  completed: boolean;
  createdAt: number;
}

type TodoWithoutDescription = Omit<Todo, 'description'>;
/*
Equivalent to:
interface TodoWithoutDescription {
  title: string;
  completed: boolean;
  createdAt: number;
}
*/

Exclude<UnionType, ExcludedMembers>

Constructs a type by excluding from UnionType all union members that are assignable to ExcludedMembers.

typescript
type T0 = Exclude<'a' | 'b' | 'c', 'a'>; // type T0 = "b" | "c"
type T1 = Exclude<string | number | (() => void), Function>; // type T1 = string | number

Extract<Type, Union>

Constructs a type by extracting from Type all union members that are assignable to Union.

typescript
type T0 = Extract<'a' | 'b' | 'c', 'a' | 'f'>; // type T0 = "a"
type T1 = Extract<string | number | (() => void), Function>; // type T1 = () => void

NonNullable<Type>

Constructs a type by excluding null and undefined from Type.

typescript
type T0 = NonNullable<string | number | undefined>; // type T0 = string | number
type T1 = NonNullable<string[] | null | undefined>; // type T1 = string[]

Parameters<Type>

Constructs a tuple type of the parameters of a function type Type. If Type is not a function type, Parameters<Type> resolves to unknown[].

typescript
declare function f1(arg: { a: number; b: string }): void;
type T0 = Parameters<typeof f1>; // type T0 = [{ a: number; b: string }]

declare function f2(arg1: number, arg2: string): number;
type T1 = Parameters<typeof f2>; // type T1 = [number, string]

ReturnType<Type>

Constructs a type consisting of the return type of function type Type.

typescript
declare function f1(): { a: number; b: string };
type T0 = ReturnType<typeof f1>; // type T0 = { a: number; b: string }

declare function f2(): Promise<number>;
type T1 = ReturnType<typeof f2>; // type T1 = Promise<number>

Awaited<Type>

This type is intended to model the type of await in async functions, specifically how it recursively unwraps Promises. It will resolve to the non-Promise type wrapped by a Promise, or the original type if it's not a Promise.

typescript
type P1 = Promise<Promise<number>>;
type A1 = Awaited<P1>; // type A1 = number

type P2 = Promise<string | boolean>;
type A2 = Awaited<P2>; // type A2 = string | boolean

type P3 = number;
type A3 = Awaited<P3>; // type A3 = number