TypeScript Cheatsheet
Basics
Use this TypeScript reference while you build software engineering projects, review code, or refresh the syntax you reach for most.
Learn TypeScript From JavaScript Variables
TypeScript is JavaScript plus a static type layer, so this reference starts with the syntax you already use: let, const, functions, objects, arrays, and modules. Use it when you are trying to learn TypeScript after you learn JavaScript, or when you need a quick check while building typed software engineering projects.
let name: string = "Alice"; // mutable, block-scoped const age: number = 30; // immutable binding var legacy: boolean = true; // function-scoped (avoid; prefer let/const) // Type inference — type is inferred when initialized let count = 0; // inferred: number const label = "beta"; // inferred: string literal "beta"
Primitive Types
| Type | Keyword | Example |
|---|---|---|
| Number | number | let n: number = 3.14 |
| String | string | let s: string = "hi" |
| Boolean | boolean | let b: boolean = true |
| BigInt | bigint | let x: bigint = 9007199254740991n |
| Symbol | symbol | let sym: symbol = Symbol("id") |
| Null | null | let n: null = null |
| Undefined | undefined | let u: undefined = undefined |
Special Types
// any — opt out of type checking entirely (avoid when possible) let whatever: any = 42; whatever = "now a string"; // OK, no error // unknown — safe top type; must narrow before use let val: unknown = fetchData(); if (typeof val === "string") { console.log(val.toUpperCase()); // OK after narrowing } // never — represents a value that never occurs function fail(msg: string): never { throw new Error(msg); } function infinite(): never { while (true) {} } // void — function returns undefined (or nothing) function log(msg: string): void { console.log(msg); } // object — any non-primitive value let obj: object = { a: 1 }; // {} — any non-null, non-undefined value (broader than object) let notNullish: {} = 42; // valid
Type Annotations
// Variable with explicit type let id: number; // Function parameter and return type function greet(name: string): string { return `Hello, ${name}`; } // Arrow function const double = (n: number): number => n * 2; // Array let nums: number[] = [1, 2, 3]; let strs: Array<string> = ["a", "b"]; // generic form let readonly: ReadonlyArray<number> = [1]; // immutable array // Tuple — fixed-length, fixed-types let pair: [string, number] = ["age", 25]; let named: [name: string, age: number] = ["Bob", 20]; // labeled tuple // Optional tuple element let triple: [string, number, boolean?] = ["x", 1]; // Rest tuple element let rest: [string, ...number[]] = ["label", 1, 2, 3];
Type Assertions
// as syntax (preferred in all files) const canvas = document.getElementById("c") as HTMLCanvasElement; const len = (someValue as string).length; // Angle-bracket syntax (NOT valid in .tsx files) const canvas2 = <HTMLCanvasElement>document.getElementById("c"); // Double assertion — when types don't overlap (use sparingly) const x = (value as unknown) as SpecificType; // Non-null assertion operator ! — asserts not null/undefined const el = document.getElementById("app")!; el.textContent = "hello";
Literal Types and as const
// String, number, boolean literals as types let dir: "left" | "right" = "left"; const PI: 3.14159 = 3.14159; let flag: true = true; // as const — narrows inferred types to literals, makes arrays readonly tuples const config = { host: "localhost", port: 3000 } as const; // config.host: "localhost" config.port: 3000 (not number) const directions = ["left", "right", "up"] as const; // type: readonly ["left", "right", "up"] // const enum alternative const STATUS = { ACTIVE: "active", INACTIVE: "inactive" } as const; type Status = typeof STATUS[keyof typeof STATUS]; // "active" | "inactive"
satisfies Operator (TS 4.9+)
// Validates a value matches a type WITHOUT widening the inferred type type Colors = "red" | "green" | "blue"; const palette = { red: [255, 0, 0], green: "#00ff00", } satisfies Record<Colors, string | number[]>; palette.red; // type: number[] (not widened to string | number[]) palette.green; // type: string
Type Inference
let x = [1, 2, 3]; // number[] let fn = (a: number) => a; // (a: number) => number const obj = { x: 0, y: 0 }; // { x: number; y: number } // Contextual typing — inferred from callback context [1, 2, 3].forEach(n => console.log(n.toFixed())); // n: number // Return type inference function add(a: number, b: number) { return a + b; // inferred: number }
typeof, keyof, instanceof
// typeof in type position — get type of a value let s = "hello"; type T = typeof s; // string const config = { port: 3000 }; type Config = typeof config; // { port: number } // keyof — union of property keys type Keys = keyof { a: number; b: string }; // "a" | "b" type ArrayKeys = keyof string[]; // number | "length" | "push" | ... // instanceof — narrow to class instance if (err instanceof Error) { console.log(err.message); // Error } if (obj instanceof Map) { obj.get("key"); } // typeof in runtime narrowing function pad(val: string | number) { if (typeof val === "string") return val.padStart(10); return val.toFixed(2); }
Destructuring with Types
// Array destructuring const [first, second, ...rest]: number[] = [1, 2, 3, 4]; // Object destructuring with inline type const { name, age = 25 }: { name: string; age?: number } = user; // Rename on destructure const { x: xPos, y: yPos }: { x: number; y: number } = point; // Nested destructuring const { address: { city } } = user; // Function parameter destructuring function display({ title, count = 0 }: { title: string; count?: number }) { console.log(title, count); }
Spread and Rest
// Array spread const a = [1, 2, 3]; const b = [...a, 4, 5]; // [1, 2, 3, 4, 5] // Object spread (last wins on collision) const obj1 = { x: 1, z: 0 }; const obj2 = { ...obj1, y: 2, z: 9 }; // { x: 1, z: 9, y: 2 } // Rest parameters function sum(...nums: number[]): number { return nums.reduce((a, b) => a + b, 0); } // Spread as arguments const nums = [1, 2, 3] as const; Math.max(...nums);
Optional Chaining and Nullish Operators
// Optional chaining — short-circuits on null/undefined const city = user?.address?.city; const first = arr?.[0]; const result = obj?.method?.(); // Nullish coalescing ?? — right side only when left is null/undefined const name = user.name ?? "Anonymous"; // Nullish assignment let a: number | null = null; a ??= 42; // assign if null/undefined: a === 42 let b = 0; b ||= 10; // assign if falsy: b === 10 b &&= b * 2; // assign if truthy: b === 20
Template Literal Types
type Dir = "top" | "bottom"; type Margin = `margin-${Dir}`; // "margin-top" | "margin-bottom" type EventName<T extends string> = `on${Capitalize<T>}`; type ClickEvent = EventName<"click">; // "onClick" // Intrinsic string manipulation types type U = Uppercase<"hello">; // "HELLO" type L = Lowercase<"WORLD">; // "world" type C = Capitalize<"foo">; // "Foo" type N = Uncapitalize<"FooBar">; // "fooBar"
tsconfig.json Key Options
{
"compilerOptions": {
"target": "ES2022",
"module": "NodeNext",
"moduleResolution": "NodeNext",
"strict": true,
"noUncheckedIndexedAccess": true,
"exactOptionalPropertyTypes": true,
"noImplicitReturns": true,
"noFallthroughCasesInSwitch": true,
"esModuleInterop": true,
"skipLibCheck": true,
"outDir": "./dist",
"rootDir": "./src"
}
}
"strict": trueenables:strictNullChecks,strictFunctionTypes,strictBindCallApply,noImplicitAny,noImplicitThis,alwaysStrict,useUnknownInCatchVariables.