Skip to main content

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;
}
}