typescript-cheatsheet
TypeScript Cheatsheet
Section titled “TypeScript Cheatsheet”Type Basics
Section titled “Type Basics”// Primitivesconst name: string = 'John'const age: number = 30const isActive: boolean = trueconst nothing: null = nullconst notDefined: undefined = undefined
// Arraysconst numbers: number[] = [1, 2, 3]const strings: Array<string> = ['a', 'b', 'c']
// Tupleconst tuple: [string, number] = ['hello', 42]
// Objectconst user: { name: string; age: number } = { name: 'John', age: 30 }
// Unionconst value: string | number = 'hello'
// Literalconst direction: 'up' | 'down' | 'left' | 'right' = 'up'
// Any vs Unknownconst anyValue: any = 'anything' // ❌ Avoidconst unknownValue: unknown = 'safe' // ✅ Prefer, requires narrowingType Aliases & Interfaces
Section titled “Type Aliases & Interfaces”// Type Aliastype Point = { x: number y: number}
// Interface (preferred for objects)interface User { id: string name: string email?: string // Optional readonly createdAt: Date // Readonly}
// Extendinginterface Admin extends User { permissions: string[]}
// Intersectiontype AdminUser = User & { permissions: string[] }Generics
Section titled “Generics”// Generic functionfunction identity<T>(value: T): T { return value}
// Generic with constraintfunction getLength<T extends { length: number }>(item: T): number { return item.length}
// Generic interfaceinterface ApiResponse<T> { data: T status: number message: string}
// Generic with defaulttype Container<T = string> = { value: T}
// Multiple genericsfunction merge<T, U>(obj1: T, obj2: U): T & U { return { ...obj1, ...obj2 }}Utility Types
Section titled “Utility Types”interface User { id: string name: string email: string age: number}
// Partial - all optionaltype PartialUser = Partial<User>
// Required - all requiredtype RequiredUser = Required<User>
// Readonly - all readonlytype ReadonlyUser = Readonly<User>
// Pick - select propertiestype UserName = Pick<User, 'id' | 'name'>
// Omit - exclude propertiestype UserWithoutEmail = Omit<User, 'email'>
// Record - key-value maptype UserMap = Record<string, User>
// Extract - extract from uniontype StringOrNumber = string | number | booleantype OnlyStrings = Extract<StringOrNumber, string>
// Exclude - exclude from uniontype NotString = Exclude<StringOrNumber, string>
// NonNullable - remove null/undefinedtype MaybeString = string | null | undefinedtype DefinitelyString = NonNullable<MaybeString>
// ReturnType - get function return typefunction getUser() { return { name: 'John' } }type UserReturn = ReturnType<typeof getUser>
// Parameters - get function parameterstype GetUserParams = Parameters<typeof getUser>
// Awaited - unwrap Promisetype ResolvedUser = Awaited<Promise<User>>Conditional Types
Section titled “Conditional Types”// Basic conditionaltype IsString<T> = T extends string ? true : false
// Infer keywordtype UnwrapPromise<T> = T extends Promise<infer U> ? U : T
// Distributive conditionaltype ToArray<T> = T extends any ? T[] : nevertype Result = ToArray<string | number> // string[] | number[]
// NonDistributivetype ToArrayNonDist<T> = [T] extends [any] ? T[] : neverTemplate Literal Types
Section titled “Template Literal Types”type Color = 'red' | 'green' | 'blue'type Size = 'small' | 'medium' | 'large'
// Combinetype ColorSize = `${Color}-${Size}`// 'red-small' | 'red-medium' | 'red-large' | ...
// Event handlerstype EventName = 'click' | 'focus' | 'blur'type EventHandler = `on${Capitalize<EventName>}`// 'onClick' | 'onFocus' | 'onBlur'Mapped Types
Section titled “Mapped Types”// Basic mapped typetype Optional<T> = { [K in keyof T]?: T[K]}
// With key remappingtype Getters<T> = { [K in keyof T as `get${Capitalize<string & K>}`]: () => T[K]}
// Filter keystype OnlyStrings<T> = { [K in keyof T as T[K] extends string ? K : never]: T[K]}Type Guards
Section titled “Type Guards”// typeof guardfunction process(value: string | number) { if (typeof value === 'string') { return value.toUpperCase() // string } return value.toFixed(2) // number}
// instanceof guardclass Dog { bark() {} }class Cat { meow() {} }
function makeSound(animal: Dog | Cat) { if (animal instanceof Dog) { animal.bark() } else { animal.meow() }}
// in guardinterface Bird { fly(): void }interface Fish { swim(): void }
function move(animal: Bird | Fish) { if ('fly' in animal) { animal.fly() } else { animal.swim() }}
// Custom type guardfunction isString(value: unknown): value is string { return typeof value === 'string'}
// Assertion functionfunction assertIsString(value: unknown): asserts value is string { if (typeof value !== 'string') { throw new Error('Not a string') }}Discriminated Unions
Section titled “Discriminated Unions”// With type discriminanttype Success<T> = { type: 'success'; data: T }type Error = { type: 'error'; message: string }type Loading = { type: 'loading' }
type State<T> = Success<T> | Error | Loading
function handle<T>(state: State<T>) { switch (state.type) { case 'success': return state.data // T case 'error': return state.message // string case 'loading': return null }}
// Exhaustive checkfunction assertNever(value: never): never { throw new Error(`Unexpected value: ${value}`)}Branded Types
Section titled “Branded Types”// Create branded typetype Brand<K, T> = K & { __brand: T }
type UserId = Brand<string, 'UserId'>type OrderId = Brand<string, 'OrderId'>
// Constructor functionsfunction createUserId(id: string): UserId { return id as UserId}
function createOrderId(id: string): OrderId { return id as OrderId}
// Usage - prevents mixingfunction getOrder(orderId: OrderId, userId: UserId) {}
const userId = createUserId('user-123')const orderId = createOrderId('order-456')
getOrder(orderId, userId) // ✅ OK// getOrder(userId, orderId) // ❌ Error - types don't matchModule Declarations
Section titled “Module Declarations”// Declare module for untyped packagedeclare module 'untyped-package' { export function doSomething(): void export const value: string}
// Augment existing moduledeclare module 'express' { interface Request { user?: { id: string } }}
// Declare globaldeclare global { interface Window { myGlobal: string }}TSConfig Essentials
Section titled “TSConfig Essentials”{ "compilerOptions": { // Strictness "strict": true, "noUncheckedIndexedAccess": true, "noImplicitOverride": true,
// Modules "module": "ESNext", "moduleResolution": "bundler", "esModuleInterop": true,
// Output "target": "ES2022", "lib": ["ES2022", "DOM"],
// Performance "skipLibCheck": true, "incremental": true,
// Paths "baseUrl": ".", "paths": { "@/*": ["./src/*"] } }}Best Practices
Section titled “Best Practices”// ✅ Prefer interface for objectsinterface User { name: string}
// ✅ Use const assertionsconst routes = ['home', 'about'] as const
// ✅ Use satisfies for validationconst config = { api: 'https://api.example.com'} satisfies Record<string, string>
// ✅ Use unknown over anyfunction parse(input: unknown) { if (typeof input === 'string') { return JSON.parse(input) }}
// ✅ Explicit return types for public APIsexport function getUser(id: string): User | null { // ...}
// ❌ Avoidconst data: any = fetchData()data.anything.goes.wrong // No type safety