TypeScript Cheatsheet
Basics
Use this TypeScript reference while you build software engineering projects, review code for technical interview prep, or polish examples for a software engineer resume.
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.