Sheet ⁨04⁩ · ⁨Cheatsheets⁩Surveyed ⁨2026⁩
Cheatsheets

TypeScript

A TypeScript reference covering the type syntax engineers use most, from unions and generics to utility types, modern techniques (satisfies, const type params, template literal types, using), and the TypeScript 7 native compiler.

8 Categories21 Sections25 ExamplesPublished: 30 Aug 2026Updated: 31 Aug 2026
TypeScriptTypeScript 7TypesGenericsUtility TypessatisfiesType GuardsJavaScript

A fast reference for the TypeScript you write every day: primitives and unions, interfaces versus type aliases, generics and constraints, the built-in utility types (Partial, Pick, Omit, Record, ReturnType), type guards and narrowing, and declaration merging. It also covers modern type techniques (satisfies, const type parameters, template literal types, conditional types with infer, variadic tuples, NoInfer, and using) and how they behave under the TypeScript 7 native compiler.

Basic Types

The primitive and composite types you annotate with every day.

Primitives and unions

Annotate variables, and combine types with unions and literals.

Primitives and a union

Union types allow a value to be one of several types; literal unions restrict it to specific values.

Code
let name: string = 'Ada';
let count: number = 42;
let active: boolean = true;
// union: one of several types
let id: string | number = 'abc';
id = 123;
// literal union: one of a fixed set of values
type Status = 'idle' | 'loading' | 'done';
let s: Status = 'idle';
  • Prefer literal unions over loose strings for state.

Arrays and tuples

Arrays hold many of one type; tuples fix the length and the type at each position.

Code
const nums: number[] = [1, 2, 3];
const pair: [string, number] = ['age', 30]; // tuple

any vs unknown vs never

The three special types and when each is correct.

unknown forces a check

Prefer unknown over any; it keeps type safety by forcing you to narrow before use. never represents a value that can't happen.

Code
let a: any = 5; // opts out of checking (avoid)
let u: unknown = 5; // must narrow before use
if (typeof u === 'number') u.toFixed(2);

Interfaces and Type Aliases

The two ways to name object shapes, and when to use each.

interface vs type

Both describe shapes; interfaces merge and extend, type aliases can express unions.

Interface and type alias

Use interface for object shapes you may extend or implement; use type when you need unions, intersections, or mapped types.

Code
interface User {
id: string;
name: string;
email?: string; // optional
}
type Point = {x: number; y: number};
type Id = string | number; // only a type alias can do this
  • Interfaces with the same name merge; type aliases do not.

Extending and intersecting

extends adds to an interface; & intersects types into one combined shape.

Code
interface Admin extends User {
role: 'admin';
}
type Timestamped = Point & {createdAt: number}; // intersection

readonly and index signatures

Lock fields and model open-ended key maps.

readonly + index signature

readonly prevents reassignment; an index signature types objects used as dictionaries.

Code
interface Config {
readonly apiUrl: string; // can't be reassigned
[key: string]: string; // any string key -> string
}

Generics

Reusable, type-safe building blocks parameterized by type.

Generic functions and constraints

Write functions that work over many types while keeping the link between input and output.

A generic function

T is inferred from the argument, so the return type tracks the input type.

Code
function first<T>(arr: T[]): T | undefined {
return arr[0];
}
const n = first([1, 2, 3]); // n: number | undefined

Constraining a type parameter

extends constrains T to types that have a length, so the function only accepts things it can measure.

Code
function longest<T extends {length: number}>(a: T, b: T): T {
return a.length >= b.length ? a : b;
}

Generic interfaces and defaults

Parameterize object shapes and provide default type arguments.

Generic interface with a default

The default type argument (= unknown) is used when the caller does not specify one.

Code
interface ApiResponse<T = unknown> {
data: T;
status: number;
}
const r: ApiResponse<User> = {data: user, status: 200};

Built-in Utility Types

The standard-library type transformers you reach for constantly.

Partial, Required, Readonly

Flip modifiers across every property of a type.

Partial and Required

Handy for update payloads (Partial) and for locking a value (Readonly).

Code
type Draft = Partial<User>; // all fields optional
type Full = Required<User>; // all fields required
type Frozen = Readonly<User>; // all fields readonly

Pick, Omit, Record

Select, remove, and build key/value maps.

Pick, Omit, Record

Pick and Omit derive new shapes from existing ones; Record builds a dictionary type.

Code
type Credentials = Pick<User, 'id' | 'email'>; // keep some keys
type PublicUser = Omit<User, 'email'>; // drop some keys
type UsersById = Record<string, User>; // map of key -> User
  • Deriving types with Pick/Omit keeps them in sync with the source type.

ReturnType, Parameters, Awaited

Extract types from functions and promises.

Infer from a function and a promise

These pull types out of existing values so you do not repeat yourself.

Code
function makeUser() { return {id: '1', name: 'Ada'}; }
type NewUser = ReturnType<typeof makeUser>;
type Args = Parameters<typeof makeUser>;
type Resolved = Awaited<Promise<number>>; // number

Type Guards and Narrowing

Convince the compiler a value is a more specific type at runtime.

typeof, in, and instanceof

The built-in ways to narrow a union.

Narrowing a union

The in operator narrows the union so each branch sees the right shape.

Code
function area(shape: {r: number} | {w: number; h: number}) {
if ('r' in shape) return Math.PI * shape.r ** 2;
return shape.w * shape.h;
}

Custom type guard

A function returning `x is User` teaches the compiler to narrow after the check passes.

Code
function isUser(x: unknown): x is User {
return typeof x === 'object' && x !== null && 'id' in x;
}

Modern Type Techniques

Newer type-level tools that make TypeScript expressive, all current under the TypeScript 7 compiler.

The satisfies operator

Check a value against a type without widening it, so you keep the precise inferred type.

satisfies keeps the narrow type

satisfies validates the value against the type but leaves the inferred type intact, so you get checking without losing literal precision.

Code
type Route = Record<string, {method: 'GET' | 'POST'}>;
// annotation widens: method is 'GET' | 'POST'
const a: Route = {home: {method: 'GET'}};
// satisfies checks AND keeps the literal type
const routes = {home: {method: 'GET'}} satisfies Route;
routes.home.method; // narrowed to 'GET'

const type parameters

Infer the narrowest literal, readonly type for a generic argument.

A const generic

The const modifier tells TypeScript to infer literal, readonly types instead of widening them.

Code
function tuple<const T extends readonly unknown[]>(...args: T): T {
return args;
}
const t = tuple('a', 1); // readonly ['a', 1], not (string | number)[]

Template literal types

Build string types by interpolating other types.

Typed event handler names

Template literal types plus the intrinsic helpers (Uppercase, Lowercase, Capitalize) generate precise string unions.

Code
type Event = 'click' | 'focus';
type Handler = `on${Capitalize<Event>}`; // 'onClick' | 'onFocus'

Mapped types with key remapping

Transform both the keys and values of a type with the as clause.

Generate getters from a type

The as clause in a mapped type renames keys; mapping a key to never filters it out entirely.

Code
type Getters<T> = {
[K in keyof T as `get${Capitalize<string & K>}`]: () => T[K];
};
type G = Getters<{name: string}>; // {getName: () => string}

Conditional types and infer

Pick a type based on a condition and extract pieces with infer.

Unwrap an array element type

A conditional type (T extends X ? A : B) combined with infer pulls a type out of another type.

Code
type ElementOf<T> = T extends (infer U)[] ? U : never;
type N = ElementOf<number[]>; // number

Variadic tuple types

Spread and compose tuple types, handy for typing concat, curry, and the like.

Prepend an element to a tuple

The ...rest spread inside tuple types composes fixed and variable-length tuples.

Code
type Prepend<T, Arr extends readonly unknown[]> = [T, ...Arr];
type R = Prepend<0, [1, 2]>; // [0, 1, 2]

NoInfer

Stop a type parameter from being inferred from one position.

Force inference from the first argument

NoInfer<T> (built in since TypeScript 5.4) prevents the compiler from widening C based on the fallback argument.

Code
function paint<C extends string>(colors: C[], fallback: NoInfer<C>): void {}
paint(['red', 'blue'], 'red'); // fallback constrained to 'red' | 'blue'

Explicit resource management (using)

Deterministically dispose resources with using and await using.

using a disposable

using (and await using for Symbol.asyncDispose) calls the disposer when the scope exits, like RAII, so you never forget to clean up.

Code
function openFile(path: string): Disposable & {read(): string} {
return {read: () => '...', [Symbol.dispose]() {/* close */}};
}
function run() {
using file = openFile('a.txt');
file.read();
} // Symbol.dispose() runs automatically at scope exit

The TypeScript 7 Native Compiler

What the native (Go) compiler changes, and what it deliberately does not.

tsc on the native compiler

TypeScript 7 is a native port of the compiler focused on speed, with the same type-checking semantics as 6.x.

Same commands, much faster

TypeScript 7 (GA July 2026) is a native Go port that type-checks roughly 8-12x faster than 6.x on large projects. It is a port, not a rewrite, so your types and tsconfig keep working unchanged.

Code
Terminal window
# Type-check only, no emit
tsc --noEmit
# Fast feedback in watch mode
tsc --watch
  • Because 7.0 preserves semantics, everything else in this cheatsheet is still valid.
  • TypeScript 6.0 was the transition release that turned earlier deprecations and stricter defaults on; clear those warnings before moving to 7.

Modules and Declaration Merging

Organize types across files and extend existing ones.

Type-only imports

Import and export types without pulling in runtime code.

import type

import type is erased at compile time, so it never affects the JS bundle.

Code
import type {User} from './models';
export type {User};

Declaration merging

Add to an existing interface, including third-party ones.

Augment an interface

Re-declaring an interface merges the members, which is how you augment globals or library types.

Code
interface Window {
analytics?: {track(event: string): void};
}

Was this useful?

You might also enjoy

More posts on similar topics

Dart

Dart is a statically-typed, strongly null-safe programming language designed for building fast, multi-platform applications. Created by Google, Dart ships with its own compiler, formatter, and package

#Dart#Programming#Type Safety+5 tags
read more

JavaScript

JavaScript is a high-level programming language that powers the web. It supports object-oriented, functional, and event-driven programming styles. The sections below cover JavaScript syntax and metho

#JavaScript#ES6#Web Development+3 tags
read more

Go

Go is a statically typed, compiled programming language designed with simplicity and efficiency in mind. It excels at concurrent programming, which makes it a good fit for fast, scalable server applic

#Go#Golang#Programming+6 tags
read more

Python

  • Mohammad Abu Mattar
  • Programming Language
  • Python
  • Scripting
  • Object Oriented
  • Web Development
  • Data Science

Python is an interpreted, high-level programming language known for its readability and simplicity. It supports multiple programming paradigms including procedural, object-oriented, and functional pro

#Python#Programming#Scripting+6 tags
read more

Python Virtual Environments Cheatsheet

A fast reference for keeping Python projects isolated and reproducible. It covers creating and activating environments with venv, installing packages with pip, locking dependencies with requirements f

#Python#Virtualenv#Pip+5 tags
read more

GitHub Actions

GitHub Actions runs your CI/CD directly from YAML files in .github/workflows/, and most of the job is knowing which key does what. A workflow reacts to events, splits into jobs that run on runners,

#GitHub Actions#Workflow#CI/CD+5 tags
read more

6 related posts