TypeScript Cheatsheet
A comprehensive reference for TypeScript's type system, interfaces, generics, and advanced patterns. From basic types to complex mapped types.
1Basic Types
TypeScript extends JavaScript with static type annotations. These are the fundamental types you will use in every project.
// Primitives
let name: string = "Alice";
let age: number = 30;
let isActive: boolean = true;
// Arrays
let nums: number[] = [1, 2, 3];
let names: Array<string> = ["a", "b"];
// Tuple (fixed-length array with specific types)
let pair: [string, number] = ["age", 30];
// Any (escape hatch - avoid when possible)
let flexible: any = "hello";
flexible = 42; // No error
// Unknown (safer than any)
let input: unknown = getUser();
if (typeof input === "string") {
console.log(input.toUpperCase()); // OK after check
}
// Void, Null, Undefined
function log(msg: string): void { console.log(msg); }
let nothing: null = null;
let undef: undefined = undefined;
// Never (function that never returns)
function fail(msg: string): never {
throw new Error(msg);
}2Interfaces
Interfaces define the shape of objects. They are one of TypeScript's most powerful features for describing contracts in your code.
// Basic interface
interface User {
name: string;
age: number;
email?: string; // Optional property
readonly id: number; // Cannot be changed
}
const user: User = { name: "Alice", age: 30, id: 1 };
// Extending interfaces
interface Employee extends User {
department: string;
salary: number;
}
// Index signatures
interface StringMap {
[key: string]: string;
}
// Function interface
interface SearchFunc {
(query: string, limit: number): string[];
}
// Multiple extends
interface Manager extends Employee {
reports: Employee[];
}3Type Aliases & Unions
Type aliases create custom names for types. Union and intersection types combine existing types in powerful ways.
// Type alias
type ID = string | number;
type Point = { x: number; y: number };
// Union types (either/or)
type Status = "loading" | "success" | "error";
let current: Status = "loading";
// Intersection types (combine both)
type Named = { name: string };
type Aged = { age: number };
type Person = Named & Aged;
const person: Person = { name: "Alice", age: 30 };
// Literal types
type Direction = "north" | "south" | "east" | "west";
type HttpCode = 200 | 301 | 404 | 500;
// Template literal types
type EventName = `on${"Click" | "Hover" | "Focus"}`;
// "onClick" | "onHover" | "onFocus"4Generics
Generics allow you to write reusable components that work with any type while maintaining type safety.
// Generic function
function identity<T>(value: T): T {
return value;
}
identity<string>("hello"); // "hello"
identity(42); // Type inferred as number
// Generic interface
interface ApiResponse<T> {
data: T;
status: number;
message: string;
}
const users: ApiResponse<User[]> = fetchUsers();
// Generic constraints
function getLength<T extends { length: number }>(item: T): number {
return item.length;
}
getLength("hello"); // OK
getLength([1, 2, 3]); // OK
// getLength(42); // Error: no length property
// Generic with default
type Container<T = string> = { value: T };
const box: Container = { value: "hello" }; // T defaults to string5Enums
Enums define a set of named constants. TypeScript supports both numeric and string enums.
// Numeric enum (auto-increments from 0)
enum Direction {
Up, // 0
Down, // 1
Left, // 2
Right, // 3
}
let dir: Direction = Direction.Up;
// String enum
enum Status {
Active = "ACTIVE",
Inactive = "INACTIVE",
Pending = "PENDING",
}
// Const enum (inlined at compile time)
const enum Color {
Red = "RED",
Green = "GREEN",
Blue = "BLUE",
}
// Use as type
function move(direction: Direction): void {
// ...
}6Type Guards & Narrowing
Type guards narrow the type within conditional blocks, letting TypeScript understand which type you are working with at runtime.
// typeof guard
function process(value: string | number) {
if (typeof value === "string") {
return value.toUpperCase(); // string methods OK
}
return value.toFixed(2); // number methods OK
}
// instanceof guard
function handleError(err: Error | string) {
if (err instanceof Error) {
console.log(err.message);
} else {
console.log(err);
}
}
// Custom type guard (type predicate)
interface Cat { meow(): void }
interface Dog { bark(): void }
function isCat(pet: Cat | Dog): pet is Cat {
return (pet as Cat).meow !== undefined;
}
// Discriminated unions
type Shape =
| { kind: "circle"; radius: number }
| { kind: "rect"; width: number; height: number };
function area(shape: Shape): number {
switch (shape.kind) {
case "circle": return Math.PI * shape.radius ** 2;
case "rect": return shape.width * shape.height;
}
}7Utility Types
TypeScript includes built-in utility types that transform existing types. These are essential for real-world applications.
interface User {
name: string;
age: number;
email: string;
}
// Partial - all properties optional
type PartialUser = Partial<User>;
// { name?: string; age?: number; email?: string }
// Required - all properties required
type RequiredUser = Required<PartialUser>;
// Pick - select specific properties
type UserName = Pick<User, "name" | "email">;
// { name: string; email: string }
// Omit - exclude specific properties
type UserWithoutEmail = Omit<User, "email">;
// { name: string; age: number }
// Record - key-value map type
type Scores = Record<string, number>;
const scores: Scores = { math: 95, english: 88 };
// Readonly - all properties readonly
type FrozenUser = Readonly<User>;
// ReturnType - extract function return type
type Result = ReturnType<typeof fetchUser>;
// Exclude / Extract
type T = Exclude<"a" | "b" | "c", "a">; // "b" | "c"
type U = Extract<"a" | "b" | "c", "a">; // "a"8Functions
TypeScript adds type annotations to function parameters, return types, and supports overloads for complex function signatures.
// Typed function
function add(a: number, b: number): number {
return a + b;
}
// Arrow function with types
const multiply = (a: number, b: number): number => a * b;
// Optional and default parameters
function greet(name: string, greeting?: string): string {
return `${greeting ?? "Hello"}, ${name}!`;
}
// Rest parameters
function sum(...nums: number[]): number {
return nums.reduce((a, b) => a + b, 0);
}
// Function type
type MathOp = (a: number, b: number) => number;
const divide: MathOp = (a, b) => a / b;
// Function overloads
function parse(input: string): number;
function parse(input: number): string;
function parse(input: string | number) {
return typeof input === "string"
? parseInt(input) : input.toString();
}9Classes
TypeScript classes add access modifiers, abstract classes, and interface implementation on top of JavaScript classes.
class Animal {
// Access modifiers
public name: string;
protected species: string;
private _age: number;
constructor(name: string, species: string, age: number) {
this.name = name;
this.species = species;
this._age = age;
}
// Getter
get age(): number { return this._age; }
// Method
describe(): string {
return `${this.name} is a ${this.species}`;
}
}
// Inheritance
class Dog extends Animal {
breed: string;
constructor(name: string, breed: string, age: number) {
super(name, "Dog", age);
this.breed = breed;
}
}
// Implements interface
interface Loggable { log(): void; }
class Logger implements Loggable {
log() { console.log("Logged"); }
}
// Abstract class
abstract class Shape {
abstract area(): number;
describe() { return `Area: ${this.area()}`; }
}10Advanced Types
Advanced type features like mapped types, conditional types, and infer unlock powerful type-level programming.
// Mapped types
type Optional<T> = {
[K in keyof T]?: T[K];
};
// Conditional types
type IsString<T> = T extends string ? "yes" : "no";
type A = IsString<string>; // "yes"
type B = IsString<number>; // "no"
// Infer keyword
type UnwrapPromise<T> =
T extends Promise<infer U> ? U : T;
type X = UnwrapPromise<Promise<string>>; // string
// Keyof and typeof
const config = { port: 3000, host: "localhost" };
type Config = typeof config;
type ConfigKey = keyof Config; // "port" | "host"
// Indexed access types
type Port = Config["port"]; // number
// Type assertions
const input = document.getElementById("name") as HTMLInputElement;
// or: const input = <HTMLInputElement>document.getElementById("name");
// Satisfies operator (TS 4.9+)
const palette = {
red: [255, 0, 0],
green: "#00ff00",
} satisfies Record<string, string | number[]>;Ready to practice TypeScript?
Master TypeScript syntax through interactive fill-in-the-blank exercises. Build type-safe muscle memory today.
Start Practicing TypeScript