TypeScript Cheat Sheet: Types, Interfaces, Generics, and Utility Types
Introduction
TypeScript adds static types to JavaScript. This cheat sheet gives you the type syntax you reach for most often. For a guided introduction, follow the TypeScript lessons on this site.
Prerequisites
- JavaScript basics
- Node.js installed
Step-by-Step Guide
Step 1: Basic types and annotations
Annotate parameters and return types, and let TypeScript infer the rest. Prefer unknown over any.
let name: string = "Ada";
let age: number = 36;
let active: boolean = true;
let ids: number[] = [1, 2, 3];
let pair: [string, number] = ["Ada", 36]; // tuple
let value: unknown; // safer than any
function add(a: number, b: number): number {
return a + b;
}
const greet = (name: string, greeting = "Hello"): string => greeting + ", " + name;Step 2: Interfaces, type aliases, and unions
Interfaces and type aliases describe object shapes. Union types allow one of several types, and literal types restrict values.
interface User {
id: number;
name: string;
email?: string; // optional
readonly createdAt: Date;
}
type Status = "pending" | "active" | "closed";
type Id = string | number;
type Admin = User & { permissions: string[] }; // intersection
const u: User = { id: 1, name: "Ada", createdAt: new Date() };Step 3: Narrowing and type guards
TypeScript narrows a union as you check it. Discriminated unions make switch statements exhaustive.
function print(value: string | number) {
if (typeof value === "string") value.toUpperCase();
else value.toFixed(2);
}
if ("email" in user) user.email;
type Shape =
| { kind: "circle"; radius: number }
| { kind: "square"; size: number };
function area(shape: Shape): number {
switch (shape.kind) {
case "circle": return Math.PI * shape.radius ** 2;
case "square": return shape.size ** 2;
}
}Step 4: Generics
Generics let a function or type work with many types while keeping them linked. Constrain them with extends.
function first<T>(items: T[]): T | undefined {
return items[0];
}
interface ApiResponse<T> {
data: T;
error?: string;
}
function longest<T extends { length: number }>(a: T, b: T): T {
return a.length >= b.length ? a : b;
}Step 5: Utility types
Built-in utility types transform existing types instead of rewriting them.
Partial<User> // all properties optional
Required<User> // all properties required
Readonly<User> // all properties readonly
Pick<User, "id" | "name"> // only these keys
Omit<User, "email"> // everything except these keys
Record<string, number> // object with string keys and number values
ReturnType<typeof add> // number
Awaited<Promise<string>> // string
NonNullable<string | null> // stringStep 6: Compiler setup and commands
Turn on strict mode in every new project. The commands below install TypeScript and check your code.
npm install --save-dev typescript
npx tsc --init
npx tsc --noEmit # type-check only
// tsconfig.json (core options)
{
"compilerOptions": {
"target": "ES2022",
"module": "ESNext",
"strict": true,
"esModuleInterop": true,
"skipLibCheck": true
},
"include": ["src"]
}FAQs
- interface or type alias?
- Both describe object shapes. Use an interface for objects and class contracts, and a type alias for unions, intersections, and mapped types. Pick one convention per project.
Summary
Annotate boundaries, prefer unknown to any, model data with interfaces and unions, narrow with checks, use generics for reuse, lean on utility types, and keep strict mode on.
Related tutorials
- Linux Command Line Cheat Sheet: Files, Permissions, Processes, and Networking
- Docker and kubectl Cheat Sheet: Containers, Images, Compose, and Kubernetes
- SQL Cheat Sheet: SELECT, Joins, Aggregates, and Data Changes
- Git Cheat Sheet: Everyday Commands, Branching, and Undoing Mistakes
- Langflow Cheat Sheet: Install, Components, API Calls, and Custom Components
Comments
Log in or create a free account to join the discussion.