TypeScript Cheatsheet
Basic Types
// Primitive types
let isDone: boolean = false;
let decimal: number = 6;
let color: string = "blue";
let list: number[] = [1, 2, 3];
let tuple: [string, number] = ["hello", 10];
// Special types
let notSure: any = 4;
let u: undefined = undefined;
let n: null = null;
let v: void = undefined;
let nv: never = (() => { throw new Error(); })();
Interfaces
// Basic interface
interface User {
name: string;
age: number;
readonly id: number;
email?: string; // Optional property
}
// Interface extending another interface
interface Employee extends User {
department: string;
salary: number;
}
// Interface with method definition
interface Clickable {
onClick(): void;
onDoubleClick?(event: MouseEvent): void;
}
Classes & OOP
// Abstract class
abstract class Animal {
protected name: string;
constructor(name: string) {
this.name = name;
}
abstract makeSound(): void;
move(distance: number): void {
console.log(`${this.name} moved ${distance}m.`);
}
}
// Class implementation
class Dog extends Animal {
constructor(name: string) {
super(name);
}
makeSound(): void {
console.log('Woof!');
}
}
// Access modifiers
class Account {
private balance: number;
public readonly id: string;
protected type: string;
constructor(id: string) {
this.id = id;
this.balance = 0;
this.type = 'standard';
}
}
Generics
// Generic function
function identity<T>(arg: T): T {
return arg;
}
// Generic interface
interface Collection<T> {
add(item: T): void;
remove(item: T): void;
getItems(): T[];
}
// Generic class
class Queue<T> {
private data: T[] = [];
push(item: T): void {
this.data.push(item);
}
pop(): T | undefined {
return this.data.shift();
}
}
// Generic constraints
interface Lengthwise {
length: number;
}
function loggingIdentity<T extends Lengthwise>(arg: T): T {
console.log(arg.length);
return arg;
}
Utility Types
TypeScript provides built-in utility types that help modify and work with existing types efficiently.
1️⃣ Partial<T>
→ Makes all properties optional
The Partial<T>
utility converts all properties of a type into optional ones.
type User = { id: number; name: string; age: number; };
type PartialUser = Partial<User>;
// Equivalent to:
type PartialUser = { id?: number; name?: string; age?: number; };
2️⃣ Required<T>
→ Makes all properties required
Opposite of Partial<T>
, the Required<T>
utility ensures all properties are mandatory.
type User = { id?: number; name?: string; age?: number; };
type RequiredUser = Required<User>;
// Equivalent to:
type RequiredUser = { id: number; name: string; age: number; };
3️⃣ Readonly<T>
→ Prevents modification of properties
The Readonly<T>
utility makes all properties immutable.
type User = { id: number; name: string; };
type ReadonlyUser = Readonly<User>;
// Now, ReadonlyUser properties cannot be modified:
const user: ReadonlyUser = { id: 1, name: "Ashish" };
user.id = 2; // ❌ Error: Cannot assign to 'id' because it is a read-only property.
4️⃣ Pick<T, K>
→ Selects specific properties
The Pick<T, K>
utility creates a new type with only selected properties from an existing type.
type User = { id: number; name: string; age: number; };
type UserNameOnly = Pick<User, "name">;
// Equivalent to:
type UserNameOnly = { name: string; };
5️⃣ Omit<T, K>
→ Excludes specific properties
The Omit<T, K>
utility removes certain properties from a type.
type User = { id: number; name: string; age: number; };
type UserWithoutId = Omit<User, "id">;
// Equivalent to:
type UserWithoutId = { name: string; age: number; };
6️⃣ Record<K, T>
→ Creates an object type with specific key-value pairs
The Record<K, T>
utility defines an object type with keys of type K
and values of type T
.
type UserRoles = Record<string, "admin" | "user">;
// Example usage:
const roles: UserRoles = {
ashish: "admin",
john: "user",
};
7️⃣ Exclude<T, U>
→ Removes specific types from a union
The Exclude<T, U>
utility filters out specific types from a union.
type Status = "active" | "inactive" | "banned";
type AllowedStatus = Exclude<Status, "banned">;
// Equivalent to:
type AllowedStatus = "active" | "inactive";
8️⃣ Extract<T, U>
→ Keeps only specific types from a union
The Extract<T, U>
utility extracts only the specified types from a union.
type Status = "active" | "inactive" | "banned";
type ActiveStatus = Extract<Status, "active">;
// Equivalent to:
type ActiveStatus = "active";
9️⃣ NonNullable<T>
→ Removes null
and undefined
The NonNullable<T>
utility removes null
and undefined
from a type.
type MaybeUser = string | null | undefined;
type User = NonNullable<MaybeUser>;
// Equivalent to:
type User = string;
🔟 ReturnType<T>
→ Extracts the return type of a function
The ReturnType<T>
utility gets the return type of a function.
function getUser() { return { id: 1, name: "Ashish" }; }
type User = ReturnType<typeof getUser>;
// Equivalent to:
type User = { id: number; name: string; };
🌟 Bonus: Parameters<T>
→ Extracts function parameters
The Parameters<T>
utility gets the parameter types of a function.
function add(a: number, b: number) { return a + b; }
type Params = Parameters<typeof add>;
// Equivalent to:
type Params = [number, number];
Advanced Types
// Union Types
type StringOrNumber = string | number;
// Intersection Types
type Employee = Person & Identifiable;
// Type Guards
function isString(value: any): value is string {
return typeof value === 'string';
}
// Mapped Types
type Nullable<T> = { [P in keyof T]: T[P] | null };
// Conditional Types
type NonNullable<T> = T extends null | undefined ? never : T;
Decorators
// Class Decorator
function sealed(constructor: Function) {
Object.seal(constructor);
Object.seal(constructor.prototype);
}
@sealed
class Example {
// ...
}
// Property Decorator
function required(target: Object, propertyKey: string) {
let value: any;
const getter = () => value;
const setter = (newVal: any) => {
if (newVal === undefined || newVal === null) {
throw new Error('Value is required');
}
value = newVal;
};
Object.defineProperty(target, propertyKey, {
get: getter,
set: setter,
enumerable: true,
configurable: true,
});
}
Best Practices & Common Patterns
// Type assertion
let someValue: any = "this is a string";
let strLength: number = (someValue as string).length;
// Type inference with 'as const'
const config = {
endpoint: "api.example.com",
port: 3000
} as const;
// Index signatures
interface StringMap {
[key: string]: string;
}
// Discriminated unions
interface Square {
kind: "square";
size: number;
}
interface Rectangle {
kind: "rectangle";
width: number;
height: number;
}
type Shape = Square | Rectangle;
// Type guards with discriminated unions
function getArea(shape: Shape): number {
switch (shape.kind) {
case "square":
return shape.size * shape.size;
case "rectangle":
return shape.width * shape.height;
}
}