TypeScript Cheat Sheet
TypeScript reference with generics, utility types, type guards, mapped types, and advanced patterns. Copy-ready syntax for developers.
Basic Types
| Syntax | Description | Example |
|---|---|---|
| Text type | const name: string = 'Alice' | |
| Numeric type (int & float) | const age: number = 30 | |
| True or false | const active: boolean = true | |
| Absence of value types | let x: null = null | |
| Opt out of type checking | let data: any = fetchData() | |
| Type-safe any (must narrow before use) | let input: unknown = JSON.parse(str) | |
| Function returns nothing | function log(msg: string): void {} | |
| Function never returns (throws/infinite) | function fail(msg: string): never { throw new Error(msg) } | |
| Large integer type | const big: bigint = 9007199254740991n | |
| Unique identifier type | const id: symbol = Symbol('id') |
Arrays & Tuples
| Syntax | Description | Example |
|---|---|---|
| Array of type | const nums: number[] = [1, 2, 3] | |
| Generic array syntax | const names: Array<string> = ['a', 'b'] | |
| Tuple (fixed-length typed array) | const pair: [string, number] = ['age', 30] | |
| Immutable array | const nums: readonly number[] = [1, 2, 3] | |
| Variadic tuple types | type Args = [string, ...number[]] |
Interfaces
| Syntax | Description | Example |
|---|---|---|
| Define object shape (extendable) | interface User { name: string; age: number } | |
| Extend an interface | interface Admin extends User { role: string } | |
| Type alias for object shape | type Point = { x: number; y: number } | |
| Optional property | interface User { email?: string } | |
| Read-only property | interface Config { readonly apiKey: string } | |
| Index signature | interface Dict { [key: string]: number } | |
| Object type with key K and value V | const scores: Record<string, number> = {} |
Unions
| Syntax | Description | Example |
|---|---|---|
| Union type (either A or B) | let id: string | number | |
| Intersection type (both A and B) | type Admin = User & { role: string } | |
| String literal union | type Status = 'active' | 'inactive' | 'pending' | |
| Nullable type | let user: User | null = null |
Narrowing
| Syntax | Description | Example |
|---|---|---|
| Primitive type guard | if (typeof x === 'string') x.toUpperCase() | |
| Class type guard | if (err instanceof Error) err.message | |
| Property existence check | if ('email' in user) user.email | |
| Custom type predicate | function isString(x: unknown): x is string { return typeof x === 'string' } | |
| Type assertion (use sparingly) | const el = document.getElementById('app') as HTMLDivElement | |
| Non-null assertion | const el = document.getElementById('app')! | |
| Validate type without widening (5.0+) | const config = { port: 3000 } satisfies Config |
Generics
| Syntax | Description | Example |
|---|---|---|
| Generic function | function identity<T>(val: T): T { return val } | |
| Generic interface | interface Box<T> { value: T } | |
| Constrained generic | function getLength<T extends { length: number }>(x: T) { return x.length } | |
| Default generic type | interface Container<T = string> { value: T } | |
| Multiple type parameters | function pair<T, U>(a: T, b: U): [T, U] |
Utility Types
| Syntax | Description | Example |
|---|---|---|
| Make all properties optional | Partial<User> → { name?: string; age?: number } | |
| Make all properties required | Required<Partial<User>> | |
| Make all properties readonly | Readonly<Config> | |
| Select specific properties | Pick<User, 'name' | 'email'> | |
| Remove specific properties | Omit<User, 'password'> | |
| Object with key type K, value type V | Record<string, number> | |
| Remove types from union | Exclude<'a'|'b'|'c', 'a'> → 'b'|'c' | |
| Extract types from union | Extract<'a'|'b'|'c', 'a'|'b'> → 'a'|'b' | |
| Remove null/undefined from type | NonNullable<string | null> → string | |
| Get function return type | ReturnType<typeof fn> | |
| Get function parameter types | Parameters<typeof fn> → [string, number] | |
| Unwrap Promise type | Awaited<Promise<string>> → string |
Functions
| Syntax | Description | Example |
|---|---|---|
| Function type expression | type Handler = (event: Event) => void | |
| Typed function declaration | function greet(name: string): string { return `Hi ${name}` } | |
| Optional parameter | function log(msg: string, level?: number) | |
| Default parameter | function repeat(s: string, n = 1) | |
| Rest parameter typing | function sum(...nums: number[]): number | |
| Function overloads | function parse(input: string): number;
function parse(input: number): string; |
Classes
| Syntax | Description | Example |
|---|---|---|
| Class declaration | class User { name: string; constructor(name: string) { this.name = name } } | |
| Access modifiers | class User { private password: string } | |
| Cannot be instantiated directly | abstract class Shape { abstract area(): number } | |
| Class implements interface | class Dog implements Animal { ... } | |
| Parameter property shorthand | class User { constructor(public name: string, private age: number) {} } |
Enums
| Syntax | Description | Example |
|---|---|---|
| Numeric enum | enum Direction { Up, Down, Left, Right } | |
| String enum | enum Status { Active = 'active', Inactive = 'inactive' } | |
| Inlined enum (no runtime object) | const enum Color { Red, Green, Blue } | |
| Readonly literal type assertion | const ROLES = ['admin', 'user'] as const |
Advanced
| Syntax | Description | Example |
|---|---|---|
| Union of object's keys | type UserKeys = keyof User → 'name' | 'age' | |
| Get type from value | type Config = typeof defaultConfig | |
| Indexed access type | type Name = User['name'] → string | |
| Mapped type | type Optional<T> = { [K in keyof T]?: T[K] } | |
| Conditional type | type IsString<T> = T extends string ? true : false | |
| Infer type within conditional | type Unpromise<T> = T extends Promise<infer R> ? R : T | |
| String manipulation at type level | type Event = `on${Capitalize<string>}` |
Frequently asked questions
What's the difference between interface and type?
Interfaces can be extended and merged (declaration merging), give clearer error messages, and are best for object shapes. Types support unions, intersections, mapped types, and conditional types. Use interface for objects, type for everything else.
When should I use generics?
Use generics when a function, class, or type needs to work with multiple types while maintaining type relationships. Common examples: function that returns the same type it receives, a container that holds any type, or a function that maps one type to another.
What's the difference between 'any' and 'unknown'?
any disables type checking entirely - you can do anything with it without errors. unknown requires you to narrow the type (with typeof, instanceof, etc.) before using it. unknown is always preferred because it maintains type safety.
How do I type React component props?
Use interface for props: interface ButtonProps { label: string; onClick: () => void; variant?: 'primary' | 'secondary' }. Then: function Button({ label, onClick, variant = 'primary' }: ButtonProps). Use React.FC<Props> or explicit return types.
Should I use enums or union types?
Prefer string literal unions: type Status = 'active' | 'pending' - they're simpler, tree-shakeable, and work with plain strings. Use enums only when you need numeric values or reverse mapping. 'as const' arrays can also replace enums.
What does 'satisfies' do?
satisfies (TS 5.0+) validates that a value matches a type WITHOUT widening it. const config = { port: 3000 } satisfies Config keeps the literal type {port: 3000} while ensuring it matches Config. Without satisfies, 'as Config' would widen the type.
Go from reference to real skills
Cheat sheets are great for quick lookups. Our in-depth courses take you from the fundamentals to professional-level mastery.
Browse all courses