
TypeScript Cheatsheet
19 of 19 code examples
Basic Types
Type annotations
Typeslet name: string = "Alice";
let age: number = 30;
let isActive: boolean = true;
let data: null = null;
// Arrays
let numbers: number[] = [1, 2, 3];
let names: Array<string> = ["Alice", "Bob"];
// Tuples
let person: [string, number] = ["Alice", 30];
// Union types
let id: string | number = "123";
id = 456; // Valid
Interfaces
Object shapes
Typesinterface User {
id: number;
name: string;
email?: string; // Optional
readonly createdAt: Date;
}
// Usage
let user: User = {
id: 1,
name: "Alice",
createdAt: new Date()
};
// Extending
interface Admin extends User {
permissions: string[];
}
Functions
Typed functions
Functions// Basic function
function add(a: number, b: number): number {
return a + b;
}
// Arrow function
const multiply = (x: number, y: number): number => x * y;
// Optional parameters
function greet(name: string, greeting?: string): string {
return `${greeting || "Hello"}, ${name}!`;
}
// Generic function
function identity<T>(arg: T): T {
return arg;
}
Classes
OOP with types
Classesclass Person {
private name: string;
protected age: number;
public email: string;
constructor(name: string, age: number, email: string) {
this.name = name;
this.age = age;
this.email = email;
}
greet(): string {
return `Hello, I'm ${this.name}`;
}
}
class Student extends Person {
private grade: string;
constructor(name: string, age: number, email: string, grade: string) {
super(name, age, email);
this.grade = grade;
}
}
Generics
Generic types
Advanced// Generic function
function getProperty<T, K extends keyof T>(obj: T, key: K): T[K] {
return obj[key];
}
// Generic interface
interface Repository<T> {
findById(id: string): T | null;
save(entity: T): void;
}
// Generic class
class Collection<T> {
private items: T[] = [];
add(item: T): void {
this.items.push(item);
}
get(index: number): T | undefined {
return this.items[index];
}
}
Utility Types
Built-in utilities
Advancedinterface User {
id: number;
name: string;
email: string;
age: number;
}
// Common utilities
type PartialUser = Partial<User>; // All optional
type RequiredUser = Required<User>; // All required
type UserEmail = Pick<User, 'email'>; // Pick specific
type UserWithoutId = Omit<User, 'id'>; // Exclude specific
// Record type
type UserRoles = Record<string, string>;
const roles: UserRoles = {
admin: "Administrator",
user: "Regular User"
};
Type Guards
Runtime type checking
Advanced// Type guard
function isString(value: unknown): value is string {
return typeof value === 'string';
}
function isUser(value: unknown): value is User {
return (
typeof value === 'object' &&
value !== null &&
'id' in value &&
'name' in value
);
}
// Discriminated unions
type Shape =
| { kind: 'circle'; radius: number }
| { kind: 'rectangle'; width: number; height: number };
function getArea(shape: Shape): number {
switch (shape.kind) {
case 'circle':
return Math.PI * shape.radius * shape.radius;
case 'rectangle':
return shape.width * shape.height;
}
}
Modules
Import and export
Modules// Export
export const PI = 3.14159;
export function add(a: number, b: number): number {
return a + b;
}
export default class Calculator {}
// Import
import Calculator, { PI, add } from './math';
import * as Math from './math';
// Type-only imports
import type { User } from './types';
Error Handling
Typed errors
Error Handling// Custom error
class ApiError extends Error {
constructor(
message: string,
public statusCode: number
) {
super(message);
this.name = 'ApiError';
}
}
// Result type
type Result<T, E = Error> =
| { success: true; data: T }
| { success: false; error: E };
function divide(a: number, b: number): Result<number> {
if (b === 0) {
return {
success: false,
error: new Error("Cannot divide by zero")
};
}
return {
success: true,
data: a / b
};
}
Mapped Types
Type transformations
Advanced// Basic mapped types
type Readonly<T> = {
readonly [P in keyof T]: T[P];
};
type Partial<T> = {
[P in keyof T]?: T[P];
};
// Key remapping
type Getters<T> = {
[K in keyof T as `get${Capitalize<string & K>}`]: () => T[K];
};
interface User {
name: string;
age: number;
}
type UserGetters = Getters<User>;
// { getName: () => string; getAge: () => number; }
Conditional Types
Type-level logic
Advanced// Basic conditional
type IsString<T> = T extends string ? true : false;
// Infer keyword
type ReturnType<T> = T extends (...args: any[]) => infer R ? R : never;
type MyFunc = () => string;
type MyReturn = ReturnType<MyFunc>; // string
// Array element type
type ArrayElement<T> = T extends (infer U)[] ? U : never;
// Promise unwrapping
type Awaited<T> = T extends Promise<infer U> ? U : T;
Template Literal Types
String pattern types
Advanced// Basic templates
type Greeting = `Hello ${string}`;
type EventName<T extends string> = `on${Capitalize<T>}`;
type ClickEvent = EventName<'click'>; // 'onClick'
// CSS properties
type CSSProperty<T extends string> = `--${T}`;
type PrimaryColor = CSSProperty<'primary-color'>;
// API endpoints
type HttpMethod = 'GET' | 'POST' | 'PUT' | 'DELETE';
type ApiEndpoint<M extends HttpMethod, P extends string> = `/${M}/${P}`;
type GetUsers = ApiEndpoint<'GET', 'users'>;
Branded Types
Distinct primitive types
Advanced// Branded types
type UserId = string & { __brand: 'UserId' };
type ProductId = string & { __brand: 'ProductId' };
function createUserId(id: string): UserId {
return id as UserId;
}
// Type safety
function getUser(id: UserId) { /* ... */ }
const userId = createUserId('123');
const productId = '456' as ProductId;
getUser(userId); // OK
// getUser(productId); // Error!
Decorators
Method and class decorators
Advanced// Method decorator
function Log(target: any, propertyName: string, descriptor: PropertyDescriptor) {
const method = descriptor.value;
descriptor.value = function (...args: any[]) {
console.log(`Calling ${propertyName}`);
return method.apply(this, args);
};
}
class Calculator {
@Log
add(a: number, b: number): number {
return a + b;
}
}
// Property decorator
function MinLength(length: number) {
return function (target: any, propertyName: string) {
// Validation logic here
};
}
Real-World: API Client
Typed HTTP client
Real Worldinterface ApiResponse<T> {
data: T;
message: string;
status: 'success' | 'error';
}
class ApiClient {
async get<T>(endpoint: string): Promise<ApiResponse<T>> {
const response = await fetch(endpoint);
return response.json();
}
async post<T, U>(endpoint: string, data: U): Promise<ApiResponse<T>> {
const response = await fetch(endpoint, {
method: 'POST',
headers: { 'Content-Type': 'application/json' },
body: JSON.stringify(data)
});
return response.json();
}
}
// Usage
const client = new ApiClient();
const user = await client.get<User>('/api/users/123');
Real-World: Form Validation
Type-safe forms
Real Worldinterface FormData {
name: string;
email: string;
age: number;
}
function validateForm(data: Partial<FormData>): Record<string, string> {
const errors: Record<string, string> = {};
if (!data.name) errors.name = 'Name required';
if (!data.email?.includes('@')) errors.email = 'Invalid email';
if (data.age && data.age < 0) errors.age = 'Age must be positive';
return errors;
}
// Usage
const errors = validateForm({ name: 'Alice', age: -5 });
console.log(errors); // { age: 'Age must be positive' }
Real-World: State Management
Typed Redux pattern
Real World// Action types
type Action<T extends string, P = void> = P extends void
? { type: T }
: { type: T; payload: P };
type AddTodoAction = Action<'ADD_TODO', { text: string }>;
type ToggleTodoAction = Action<'TOGGLE_TODO', { id: string }>;
type TodoAction = AddTodoAction | ToggleTodoAction;
// Reducer
function todoReducer(state: TodoState, action: TodoAction): TodoState {
switch (action.type) {
case 'ADD_TODO':
return {
...state,
todos: [...state.todos, {
id: crypto.randomUUID(),
text: action.payload.text,
completed: false
}]
};
case 'TOGGLE_TODO':
return {
...state,
todos: state.todos.map(todo =>
todo.id === action.payload.id
? { ...todo, completed: !todo.completed }
: todo
)
};
default:
return state;
}
}
keyof and typeof
Type queries
Advancedinterface User {
id: number;
name: string;
email: string;
}
// keyof - get keys as union
type UserKeys = keyof User; // "id" | "name" | "email"
// typeof - get type from value
const user = {
id: 1,
name: "Alice",
email: "alice@example.com"
};
type UserType = typeof user;
// { id: number; name: string; email: string }
// Combined usage
function getProperty<T, K extends keyof T>(obj: T, key: K): T[K] {
return obj[key];
}
const userName = getProperty(user, 'name'); // string
Index Signatures
Dynamic object keys
Advanced// String index signature
interface StringDictionary {
[key: string]: string;
}
const dict: StringDictionary = {
name: "Alice",
email: "alice@example.com"
};
// Number index signature
interface NumberArray {
[index: number]: string;
}
const arr: NumberArray = ["apple", "banana"];
// Mixed signatures
interface MixedDictionary {
[key: string]: any;
id: number; // Required property
}
const mixed: MixedDictionary = {
id: 1,
name: "Alice",
data: { age: 30 }
};