TypeScript Cheatsheet

Utility Types

Use this TypeScript reference while you build software engineering projects, review code for technical interview prep, or polish examples for a software engineer resume.

Object Transformation Utility Types

Partial<T> — Make All Properties Optional

interface User { id: number; name: string; email: string; }

type PartialUser = Partial<User>;
// { id?: number; name?: string; email?: string; }

function updateUser(id: number, data: Partial<User>): User {
  return { ...getUser(id), ...data };
}
updateUser(1, { name: "Alice" }); // only name required

Required<T> — Make All Properties Required

interface Config { host?: string; port?: number; debug?: boolean; }

type FullConfig = Required<Config>;
// { host: string; port: number; debug: boolean; }

function createServer(cfg: Required<Config>) { /* ... */ }

Readonly<T> — Make All Properties Readonly

type ImmutableUser = Readonly<User>;
// { readonly id: number; readonly name: string; readonly email: string; }

const u: Readonly<User> = { id: 1, name: "Alice", email: "a@b.com" };
// u.name = "Bob"; // Error: readonly

Record<K, V> — Map Keys to a Value Type

type Role = "admin" | "user" | "guest";
type Permissions = Record<Role, boolean>;
// { admin: boolean; user: boolean; guest: boolean; }

const perms: Record<Role, boolean> = {
  admin: true,
  user: false,
  guest: false,
};

// Dynamic string keys
type Cache = Record<string, unknown>;
const store: Cache = {};

// number keys
type Lookup = Record<number, string>;

Pick<T, K> — Select a Subset of Properties

interface Article { id: number; title: string; body: string; author: string; createdAt: Date; }

type ArticlePreview = Pick<Article, "id" | "title" | "author">;
// { id: number; title: string; author: string; }

type IdOnly = Pick<Article, "id">;

Omit<T, K> — Remove Properties

type PublicArticle = Omit<Article, "body" | "createdAt">;
// { id: number; title: string; author: string; }

type WithoutId = Omit<User, "id">;

// Common: omit sensitive fields
type SafeUser = Omit<User, "password" | "ssn">;

Union Manipulation Utility Types

Exclude<T, U> — Remove Members Assignable to U

type T1 = Exclude<"a" | "b" | "c", "a">;         // "b" | "c"
type T2 = Exclude<string | number | boolean, string>; // number | boolean
type T3 = Exclude<string | null | undefined, null | undefined>; // string

Extract<T, U> — Keep Only Members Assignable to U

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

NonNullable<T> — Remove null and undefined

type T1 = NonNullable<string | null | undefined>; // string
type T2 = NonNullable<number | undefined>;         // number
type T3 = NonNullable<null | undefined>;           // never

// Useful in pipelines
type SafeValues<T> = { [K in keyof T]: NonNullable<T[K]> };

Function Utility Types

ReturnType<T> — Extract Return Type of a Function

function greet(name: string): string { return `Hello ${name}`; }

type Greeting = ReturnType<typeof greet>; // string

// Works with any callable
type MapResult = ReturnType<typeof Array.prototype.map>; // any[]
type FetchResult = ReturnType<typeof fetch>; // Promise<Response>

// Generic function
type AsyncReturn<T extends (...args: any) => Promise<any>> =
  Awaited<ReturnType<T>>;

Parameters<T> — Extract Parameter Types as Tuple

function send(url: string, method: "GET" | "POST", body?: string): void {}

type SendParams = Parameters<typeof send>;
// [url: string, method: "GET" | "POST", body?: string | undefined]

// Access individual parameters
type FirstParam = Parameters<typeof send>[0]; // string
type SecondParam = Parameters<typeof send>[1]; // "GET" | "POST"

// Spread in function
function wrap<T extends (...args: any[]) => any>(fn: T, ...args: Parameters<T>) {
  return fn(...args);
}

ConstructorParameters<T> — Extract Constructor Parameter Types

class Point { constructor(public x: number, public y: number) {} }

type PointArgs = ConstructorParameters<typeof Point>; // [x: number, y: number]

function createInstance<T extends abstract new (...args: any[]) => any>(
  ctor: T,
  ...args: ConstructorParameters<T>
): InstanceType<T> {
  return new ctor(...args);
}

InstanceType<T> — Extract Instance Type from Constructor

class Logger { log(msg: string) {} }

type LoggerInstance = InstanceType<typeof Logger>; // Logger

// Useful when you have a class reference (not an instance)
function getMethod<T extends new (...args: any[]) => any>(
  ctor: T,
  method: keyof InstanceType<T>
) {}

Promise Utility Types

Awaited<T> — Unwrap Promise (Recursive)

type A = Awaited<Promise<string>>;           // string
type B = Awaited<Promise<Promise<number>>>;  // number
type C = Awaited<string>;                    // string (non-promise passes through)

// Useful for extracting async return types
async function loadUser(): Promise<User> { /* ... */ return user; }
type LoadedUser = Awaited<ReturnType<typeof loadUser>>; // User

String Manipulation Utility Types

type Upper  = Uppercase<"hello">;          // "HELLO"
type Lower  = Lowercase<"HELLO">;          // "hello"
type Cap    = Capitalize<"world">;         // "World"
type Uncap  = Uncapitalize<"HelloWorld">; // "helloWorld"

// Combine in template literal types
type Getter<T extends string> = `get${Capitalize<T>}`;
type Setter<T extends string> = `set${Capitalize<T>}`;

type GetName = Getter<"name">; // "getName"
type SetAge  = Setter<"age">;  // "setAge"

// Generate accessor names for all keys
type Accessors<T> = {
  [K in keyof T as `get${Capitalize<string & K>}`]: () => T[K];
} & {
  [K in keyof T as `set${Capitalize<string & K>}`]: (v: T[K]) => void;
};

ThisType<T> — Fluent Interface Helper

// Used to type `this` in object literal methods
type Builder<T> = {
  [K in keyof T]: (val: T[K]) => Builder<T>;
} & { build(): T };

// ThisType provides `this` context typing (requires --noImplicitThis or strict)
const mixin: { doSomething(this: { value: number }): void } & ThisType<{ value: number }> = {
  doSomething() {
    this.value; // number
  }
};

Composing Utility Types

// Combine Partial and Pick for update operations
type UserUpdate = Partial<Pick<User, "name" | "email">>;

// Required specific fields + optional rest
type CreatePost = Required<Pick<Post, "title" | "authorId">> & Partial<Omit<Post, "title" | "authorId">>;

// Deep partial
type DeepPartial<T> = {
  [K in keyof T]?: T[K] extends object ? DeepPartial<T[K]> : T[K];
};

// Deep readonly
type DeepReadonly<T> = {
  readonly [K in keyof T]: T[K] extends object ? DeepReadonly<T[K]> : T[K];
};

// Mutable — remove readonly from all properties
type Mutable<T> = { -readonly [K in keyof T]: T[K] };

// AllRequired — remove optional from all properties
type AllRequired<T> = { [K in keyof T]-?: T[K] };

// Flatten / Prettify — expand intersections for readability
type Prettify<T> = { [K in keyof T]: T[K] } & {};

Custom Utility Types (Common Patterns)

// ValueOf — union of all value types
type ValueOf<T> = T[keyof T];
type V = ValueOf<{ a: string; b: number }>; // string | number

// KeysOfType — keys whose values extend a given type
type KeysOfType<T, V> = {
  [K in keyof T]: T[K] extends V ? K : never;
}[keyof T];
type StringKeys = KeysOfType<{ a: string; b: number; c: string }, string>; // "a" | "c"

// PickByType — Pick properties by value type
type PickByType<T, V> = Pick<T, KeysOfType<T, V>>;

// OmitByType — Omit properties by value type
type OmitByType<T, V> = Omit<T, KeysOfType<T, V>>;

// Exact — prevent extra properties (not natively supported, approximation)
type Exact<T, Shape> = T extends Shape
  ? Exclude<keyof T, keyof Shape> extends never ? T : never
  : never;

// Merge — like Object.assign, right takes priority
type Merge<T, U> = Omit<T, keyof U> & U;

// Optional specific keys
type PartialBy<T, K extends keyof T> = Omit<T, K> & Partial<Pick<T, K>>;
type RequiredBy<T, K extends keyof T> = Omit<T, K> & Required<Pick<T, K>>;

// UnionToIntersection
type UnionToIntersection<U> =
  (U extends any ? (x: U) => void : never) extends (x: infer I) => void
    ? I
    : never;
type UI = UnionToIntersection<{ a: string } | { b: number }>;
// { a: string } & { b: number }

Quick Reference Table

Utility TypeInputOutput
Partial<T>{ a: string }{ a?: string }
Required<T>{ a?: string }{ a: string }
Readonly<T>{ a: string }{ readonly a: string }
Record<K,V>"a"|"b", number{ a: number; b: number }
Pick<T,K>T, "a"|"b"only those keys
Omit<T,K>T, "a"|"b"everything except those
Exclude<T,U>"a"|"b"|"c", "a""b"|"c"
Extract<T,U>"a"|"b"|"c", "a"|"d""a"
NonNullable<T>string|null|undefinedstring
ReturnType<T>() => stringstring
Parameters<T>(a: string) => void[string]
ConstructorParameters<T>new (n: number) => Foo[number]
InstanceType<T>typeof MyClassMyClass
Awaited<T>Promise<string>string
Uppercase<S>"hello""HELLO"
Lowercase<S>"HELLO""hello"
Capitalize<S>"foo""Foo"
Uncapitalize<S>"Foo""foo"