TypeScript Cheatsheet
Languages
22 views
Apr 2026
TypeScript Cheatsheet
Basic Types
// Primitives
let name: string = "Alice";
let age: number = 30;
let active: boolean = true;
let nothing: null = null;
let missing: undefined = undefined;
let big: bigint = 9007199254740991n;
let sym: symbol = Symbol("id");
// Any, unknown, never, void
let anything: any = 42; // opt out of type checking
let safe: unknown = 42; // must narrow before use
function fail(): never { throw new Error("!"); }
function log(): void { console.log("hi"); }
// Arrays
let nums: number[] = [1,2,3];
let strs: Array<string> = ["a","b"];
// Tuple
let pair: [string, number] = ["Alice", 30];
let labeled: [name: string, age: number] = ["Bob", 25];
// Readonly
const arr: readonly number[] = [1,2,3];
const tuple: readonly [string, number] = ["x", 1];
Interfaces & Type Aliases
// Interface (extendable, declarable)
interface User {
id: number;
name: string;
email?: string; // optional
readonly createdAt: Date; // immutable
}
interface Admin extends User {
role: "superadmin" | "moderator";
}
// Declaration merging (interfaces only)
interface Window { myPlugin: () => void; }
// Type alias (composable, unions/intersections)
type ID = string | number;
type Status = "active" | "inactive" | "pending";
type Point = { x: number; y: number };
type Point3D = Point & { z: number };
// Type vs Interface: use interface for objects/classes,
// type for unions, intersections, and mapped types
Generics
// Generic function
function identity<T>(arg: T): T { return arg; }
function first<T>(arr: T[]): T | undefined { return arr[0]; }
// Generic interface
interface Repository<T> {
findById(id: number): Promise<T>;
findAll(): Promise<T[]>;
save(entity: T): Promise<T>;
delete(id: number): Promise<void>;
}
// Generic class
class Stack<T> {
private items: T[] = [];
push(item: T): void { this.items.push(item); }
pop(): T | undefined { return this.items.pop(); }
peek(): T | undefined { return this.items[this.items.length - 1]; }
}
// Constraints
function getProperty<T, K extends keyof T>(obj: T, key: K): T[K] {
return obj[key];
}
// Default type parameters
interface Box<T = string> { value: T; }
// Conditional types
type IsArray<T> = T extends any[] ? true : false;
Utility Types
interface User {
id: number; name: string; email: string; age: number;
}
Partial<User> // all props optional
Required<User> // all props required
Readonly<User> // all props readonly
Record<string, User> // { [key: string]: User }
Pick<User, "id" | "name"> // { id, name }
Omit<User, "age"> // User without age
Exclude<string|number, number> // string
Extract<string|number, number> // number
NonNullable<string|null|undefined> // string
ReturnType<typeof fetch> // Promise<Response>
Parameters<typeof fetch> // [input, init?]
InstanceType<typeof Date> // Date
Awaited<Promise<string>> // string
Type Narrowing
// typeof guard
function double(x: string | number) {
if (typeof x === "string") return x.repeat(2);
return x * 2;
}
// instanceof guard
function process(value: Date | string) {
if (value instanceof Date) return value.toISOString();
return new Date(value).toISOString();
}
// in operator
interface Cat { meow(): void; }
interface Dog { bark(): void; }
function speak(pet: Cat | Dog) {
if ("meow" in pet) pet.meow();
else pet.bark();
}
// Discriminated union
type Shape =
| { kind: "circle"; radius: number }
| { kind: "rect"; width: number; height: number };
function area(s: Shape): number {
switch (s.kind) {
case "circle": return Math.PI * s.radius ** 2;
case "rect": return s.width * s.height;
}
}
// Type predicate
function isString(val: unknown): val is string {
return typeof val === "string";
}
// Assertion functions
function assertDefined<T>(val: T): asserts val is NonNullable<T> {
if (val == null) throw new Error("Expected defined value");
}
Enums & Literal Types
// String enum (prefer these)
enum Direction { Up = "UP", Down = "DOWN", Left = "LEFT", Right = "RIGHT" }
const d: Direction = Direction.Up;
// Numeric enum
enum Status { Active = 1, Inactive, Pending }
// Const enum (inlined at compile time)
const enum Color { Red, Green, Blue }
// Union literal (often better than enum)
type Dir = "UP" | "DOWN" | "LEFT" | "RIGHT";
// Template literal types
type EventName = `on${Capitalize<string>}`;
type Getter<T extends string> = `get${Capitalize<T>}`;
type Setter<T extends string> = `set${Capitalize<T>}`;
Classes
class Service {
// Shorthand constructor props
constructor(
private readonly name: string,
protected config: Config,
public version = "1.0"
) {}
// Abstract
abstract process(data: unknown): void;
}
// Implements interface
class UserService extends Service implements Repository<User> {
async findById(id: number): Promise<User> {
return db.query<User>("SELECT * FROM users WHERE id = ?", [id]);
}
// ...
}
// Accessors
class Temperature {
private _celsius = 0;
get fahrenheit() { return this._celsius * 9/5 + 32; }
set fahrenheit(f: number) { this._celsius = (f - 32) * 5/9; }
}
Advanced Types
// Mapped types
type Optional<T> = { [K in keyof T]?: T[K] };
type Mutable<T> = { -readonly [K in keyof T]: T[K] };
type Nullable<T> = { [K in keyof T]: T[K] | null };
// Infer
type UnpackPromise<T> = T extends Promise<infer U> ? U : T;
type FirstArg<T> = T extends (first: infer A, ...rest: any[]) => any ? A : never;
// Recursive types
type DeepPartial<T> = {
[K in keyof T]?: T[K] extends object ? DeepPartial<T[K]> : T[K];
};
// satisfies operator (TS 4.9+)
const config = {
port: 3000,
host: "localhost"
} satisfies Record<string, string | number>;
config.port.toFixed(); // still typed as number, not string|number