Skip to content

cheatnotes/typescript-cheatsheet

Folders and files

NameName
Last commit message
Last commit date

Latest commit

 

History

2 Commits
 
 
 
 
 
 
 
 
 
 
 
 

TypeScript Comprehensive Cheatsheet

Master TypeScript with this comprehensive cheatsheet covering everything from basic types and interfaces to advanced generics, decorators, and utility types. Includes practical code examples, configuration setup, and best practices.

Table of Contents

  1. Basic Types
  2. Type Annotations & Inference
  3. Interfaces & Type Aliases
  4. Functions
  5. Classes
  6. Generics
  7. Enums
  8. Union & Intersection Types
  9. Type Guards & Narrowing
  10. Utility Types
  11. Modules & Namespaces
  12. Decorators
  13. Advanced Types
  14. Type Manipulation
  15. Error Handling
  16. Configuration (tsconfig.json)
  17. Best Practices & Patterns

1. Basic Types

// Primitive Types
let isCompleted: boolean = false;
let count: number = 42;
let decimal: number = 3.14;
let hex: number = 0xf00d;
let binary: number = 0b1010;
let octal: number = 0o744;
let name: string = "TypeScript";
let template: string = `Hello, ${name}`;

// Arrays
let list: number[] = [1, 2, 3];
let genericList: Array<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 obj: object = { key: "value" };
let voidFunc: () => void = () => console.log("no return");

// Never
function error(message: string): never {
  throw new Error(message);
}
function infiniteLoop(): never {
  while (true) {}
}

// Unknown (safer than any)
let uncertain: unknown = 4;
if (typeof uncertain === "string") {
  let strLength: number = uncertain.length; // OK
}

2. Type Annotations & Inference

// Type Annotations
let variable: string = "hello";
let array: number[] = [1, 2, 3];
let object: { name: string; age: number } = { name: "John", age: 30 };

// Type Inference (automatic)
let inferred = "hello"; // TypeScript infers string
let numbers = [1, 2, 3]; // TypeScript infers number[]

// Contextual Typing
window.onmousedown = (event) => {
  console.log(event.button); // event inferred as MouseEvent
};

// Type Assertions
let someValue: unknown = "this is a string";
let strLength1: number = (someValue as string).length;
let strLength2: number = (<string>someValue).length;

// Const Assertions
const config = {
  api: "https://api.example.com",
  timeout: 3000,
} as const;

// Non-null Assertion
let maybeNull: string | null = "hello";
let definitely: string = maybeNull!;

3. Interfaces & Type Aliases

// Interface
interface User {
  readonly id: number;
  name: string;
  email?: string; // Optional property
  [key: string]: any; // Index signature
}

// Extending Interfaces
interface Admin extends User {
  role: "admin" | "superadmin";
  permissions: string[];
}

// Type Alias
type Point = {
  x: number;
  y: number;
};

type ID = string | number;
type Callback = (data: any) => void;

// Interface vs Type
interface Animal {
  name: string;
}
interface Dog extends Animal {
  breed: string;
}

type AnimalType = {
  name: string;
};
type DogType = AnimalType & {
  breed: string;
};

// Declaration Merging (only interfaces)
interface Box {
  height: number;
}
interface Box {
  width: number;
}
// Box now has both height and width

// Implementing interfaces
class Rectangle implements Point {
  x: number;
  y: number;
  constructor(x: number, y: number) {
    this.x = x;
    this.y = y;
  }
}

4. Functions

// Function Types
let myFunc: (x: number, y: number) => number;
myFunc = (a, b) => a + b;

// Optional & Default Parameters
function buildName(first: string, last?: string): string {
  return last ? `${first} ${last}` : first;
}
function multiply(a: number, b: number = 1): number {
  return a * b;
}

// Rest Parameters
function sum(...numbers: number[]): number {
  return numbers.reduce((acc, val) => acc + val, 0);
}

// Function Overloads
function add(a: number, b: number): number;
function add(a: string, b: string): string;
function add(a: any, b: any): any {
  return a + b;
}

// This Parameter
interface Card {
  suit: string;
  card: number;
}
interface Deck {
  suits: string[];
  cards: number[];
  createCardPicker(this: Deck): () => Card;
}

// Arrow Functions (lexical this)
const greet = (name: string): string => `Hello, ${name}`;

// Call Signatures
type DescribableFunction = {
  description: string;
  (someArg: number): boolean;
};
function doSomething(fn: DescribableFunction) {
  console.log(fn.description + " returned " + fn(6));
}

// Constructor Signatures
type SomeConstructor = {
  new (s: string): object;
};

5. Classes

// Basic Class
class Animal {
  // Properties
  private name: string;
  protected age: number;
  readonly species: string;
  
  // Constructor
  constructor(name: string, age: number) {
    this.name = name;
    this.age = age;
  }
  
  // Methods
  public speak(): void {
    console.log(`${this.name} makes a sound`);
  }
  
  // Getter/Setter
  get getName(): string {
    return this.name;
  }
  set setName(value: string) {
    if (value.length > 0) this.name = value;
  }
  
  // Static methods
  static create(name: string): Animal {
    return new Animal(name, 0);
  }
}

// Inheritance
class Dog extends Animal {
  private breed: string;
  
  constructor(name: string, age: number, breed: string) {
    super(name, age);
    this.breed = breed;
  }
  
  // Method override
  speak(): void {
    console.log(`${this.getName} barks`);
  }
}

// Abstract Classes
abstract class Shape {
  abstract getArea(): number;
  abstract color: string;
  
  printArea(): void {
    console.log(`Area: ${this.getArea()}`);
  }
}

class Circle extends Shape {
  color: string = "red";
  constructor(private radius: number) {
    super();
  }
  
  getArea(): number {
    return Math.PI * this.radius ** 2;
  }
}

// Parameter Properties (shorthand)
class Person {
  constructor(
    public name: string,
    private age: number,
    protected email: string,
    readonly id: number
  ) {}
}

// Implementing multiple interfaces
interface Printable {
  print(): void;
}
interface Loggable {
  log(): void;
}

class Document implements Printable, Loggable {
  print(): void { /* ... */ }
  log(): void { /* ... */ }
}

6. Generics

// Generic Functions
function identity<T>(arg: T): T {
  return arg;
}
let output = identity<string>("hello");
let inferred = identity("hello"); // Type inference

// Generic Interfaces
interface GenericRepository<T> {
  getById(id: number): T;
  getAll(): T[];
  create(item: T): T;
  update(id: number, item: T): T;
}

// Generic Classes
class Stack<T> {
  private items: T[] = [];
  
  push(item: T): void {
    this.items.push(item);
  }
  
  pop(): T | undefined {
    return this.items.pop();
  }
}

// Generic Constraints
interface HasLength {
  length: number;
}

function logLength<T extends HasLength>(arg: T): T {
  console.log(arg.length);
  return arg;
}

// Using Type Parameters in Constraints
function getProperty<T, K extends keyof T>(obj: T, key: K): T[K] {
  return obj[key];
}

// Generic with Multiple Types
function pair<T, U>(first: T, second: U): [T, U] {
  return [first, second];
}

// Default Generic Types
function createArray<T = string>(length: number, value: T): T[] {
  return Array(length).fill(value);
}

// Conditional Types with Generics
type IsString<T> = T extends string ? "yes" : "no";
type A = IsString<string>;  // "yes"
type B = IsString<number>;  // "no"

7. Enums

// Numeric Enums
enum Direction {
  Up,      // 0
  Down,    // 1
  Left,    // 2
  Right,   // 3
}

enum Status {
  Active = 1,
  Inactive,  // 2
  Pending,   // 3
}

// String Enums
enum Colors {
  Red = "RED",
  Green = "GREEN",
  Blue = "BLUE",
}

// Heterogeneous Enums (mixed)
enum Mixed {
  No = 0,
  Yes = "YES",
}

// Computed Members
enum FileAccess {
  None,
  Read = 1 << 1,
  Write = 1 << 2,
  ReadWrite = Read | Write,
}

// Const Enums (removed at compile time)
const enum ConstDirection {
  Up,
  Down,
  Left,
  Right,
}

// Reverse Mapping (only numeric enums)
enum Enum {
  A
}
let a = Enum.A;  // 0
let name = Enum[0]; // "A"

// Using enums
let dir: Direction = Direction.Up;
let color: Colors = Colors.Red;

// Enum as function parameter
function move(direction: Direction): void {
  switch (direction) {
    case Direction.Up: /* ... */ break;
    // ...
  }
}

8. Union & Intersection Types

// Union Types
type StringOrNumber = string | number;
let value: StringOrNumber = 42;
value = "hello";

function printId(id: number | string) {
  if (typeof id === "string") {
    console.log(id.toUpperCase());
  } else {
    console.log(id.toFixed(2));
  }
}

// Discriminated Unions
type Shape = 
  | { kind: "circle"; radius: number }
  | { kind: "rectangle"; width: number; height: number }
  | { kind: "triangle"; base: number; height: number };

function getArea(shape: Shape): number {
  switch (shape.kind) {
    case "circle": return Math.PI * shape.radius ** 2;
    case "rectangle": return shape.width * shape.height;
    case "triangle": return (shape.base * shape.height) / 2;
  }
}

// Intersection Types
type Employee = {
  name: string;
  id: number;
};

type Manager = {
  department: string;
  reports: string[];
};

type ManagerEmployee = Employee & Manager;

let manager: ManagerEmployee = {
  name: "John",
  id: 123,
  department: "Engineering",
  reports: ["Alice", "Bob"],
};

// Combining Unions and Intersections
type A = { a: string };
type B = { b: number };
type C = { c: boolean };

type Union = A | B | C;
type Intersection = A & B & C;

9. Type Guards & Narrowing

// typeof Type Guard
function padLeft(value: string, padding: string | number) {
  if (typeof padding === "number") {
    return Array(padding + 1).join(" ") + value;
  }
  if (typeof padding === "string") {
    return padding + value;
  }
}

// instanceof Type Guard
class Bird {
  fly(): void { /* ... */ }
}
class Fish {
  swim(): void { /* ... */ }
}

function move(animal: Bird | Fish) {
  if (animal instanceof Bird) {
    animal.fly();
  } else {
    animal.swim();
  }
}

// Custom Type Guards (type predicates)
function isFish(pet: Bird | Fish): pet is Fish {
  return (pet as Fish).swim !== undefined;
}

// in Operator Narrowing
type Cat = { meow: () => void };
type Dog = { bark: () => void };

function speak(animal: Cat | Dog) {
  if ("meow" in animal) {
    animal.meow();
  } else {
    animal.bark();
  }
}

// Equality Narrowing
function example(x: string | number, y: string | boolean) {
  if (x === y) {
    // x and y are both string
    x.toUpperCase();
    y.toLowerCase();
  }
}

// never Type for Exhaustiveness Checking
function assertNever(x: never): never {
  throw new Error("Unexpected object: " + x);
}

function handleShape(shape: Shape): string {
  switch (shape.kind) {
    case "circle": return "Circle";
    case "rectangle": return "Rectangle";
    case "triangle": return "Triangle";
    default: return assertNever(shape);
  }
}

10. Utility Types

// Partial<T> - Makes all properties optional
interface Todo {
  title: string;
  description: string;
  completed: boolean;
}
type PartialTodo = Partial<Todo>;

// Required<T> - Makes all properties required
type RequiredTodo = Required<PartialTodo>;

// Readonly<T> - Makes all properties readonly
type ReadonlyTodo = Readonly<Todo>;

// Pick<T, K> - Picks specific properties
type TodoPreview = Pick<Todo, "title" | "completed">;

// Omit<T, K> - Omits specific properties
type TodoInfo = Omit<Todo, "completed">;

// Record<K, T> - Creates type with keys K and values T
type PageInfo = Record<"home" | "about" | "contact", { title: string }>;

// Exclude<T, U> - Excludes types from union
type T0 = Exclude<"a" | "b" | "c", "a">; // "b" | "c"
type T1 = Exclude<string | number | (() => void), Function>; // string | number

// Extract<T, U> - Extracts types from union
type T2 = Extract<"a" | "b" | "c", "a" | "f">; // "a"

// NonNullable<T> - Removes null and undefined
type T3 = NonNullable<string | number | undefined | null>; // string | number

// Parameters<T> - Gets parameters of function type
type T4 = Parameters<(a: string, b: number) => void>; // [string, number]

// ConstructorParameters<T> - Gets constructor parameters
type T5 = ConstructorParameters<ErrorConstructor>; // [message?: string]

// ReturnType<T> - Gets return type
type T6 = ReturnType<() => string>; // string

// InstanceType<T> - Gets instance type
class MyClass {
  x = 0;
  y = 0;
}
type T7 = InstanceType<typeof MyClass>; // MyClass

// ThisParameterType<T> - Extracts 'this' parameter
function toHex(this: Number) {
  return this.toString(16);
}
type T8 = ThisParameterType<typeof toHex>; // Number

// OmitThisParameter<T> - Removes 'this' parameter
type T9 = OmitThisParameter<typeof toHex>; // () => string

11. Modules & Namespaces

// ===== Modules (ES6 style) =====

// Exporting
// file: math.ts
export function add(a: number, b: number): number {
  return a + b;
}

export const PI = 3.14159;

export interface Calculator {
  add(x: number, y: number): number;
}

export default class BasicCalculator implements Calculator {
  add(x: number, y: number): number {
    return x + y;
  }
}

// Importing
import BasicCalc, { add, PI, Calculator } from './math';
import * as Math from './math';
import { add as sum } from './math';

// Dynamic Imports
async function loadModule() {
  const module = await import('./math');
  module.add(5, 3);
}

// Re-exports
export { add } from './math';
export { add as sum } from './math';
export * from './math';

// ===== Namespaces =====
namespace Validation {
  export interface StringValidator {
    isValid(s: string): boolean;
  }
  
  export class LettersOnlyValidator implements StringValidator {
    isValid(s: string): boolean {
      return /^[A-Za-z]+$/.test(s);
    }
  }
}

// Using namespaces
let validator: Validation.StringValidator;
validator = new Validation.LettersOnlyValidator();

// Ambient Modules (for existing JS libraries)
declare module "some-library" {
  export function doSomething(): void;
  export const version: string;
}

// Module Augmentation
import { Observable } from "rxjs";
declare module "rxjs" {
  interface Observable<T> {
    customMethod(): void;
  }
}

12. Decorators

// Enable decorators in tsconfig.json: "experimentalDecorators": true

// Class Decorator
function sealed(constructor: Function) {
  Object.seal(constructor);
  Object.seal(constructor.prototype);
}

@sealed
class Greeter {
  greeting: string;
  constructor(message: string) {
    this.greeting = message;
  }
  greet() {
    return `Hello, ${this.greeting}`;
  }
}

// Decorator Factory
function logger(prefix: string) {
  return function (target: any) {
    console.log(`${prefix} - ${target.name}`);
  };
}

@logger("INFO")
class MyClass {}

// Method Decorator
function log(target: any, propertyKey: string, descriptor: PropertyDescriptor) {
  const original = descriptor.value;
  
  descriptor.value = function (...args: any[]) {
    console.log(`Calling ${propertyKey} with args:`, args);
    const result = original.apply(this, args);
    console.log(`Result:`, result);
    return result;
  };
  
  return descriptor;
}

class Calculator {
  @log
  add(a: number, b: number): number {
    return a + b;
  }
}

// Property Decorator
function validate(target: any, propertyKey: string) {
  let value: string;
  
  const getter = () => value;
  const setter = (newVal: string) => {
    if (newVal.length < 3) {
      throw new Error(`Invalid ${propertyKey}`);
    }
    value = newVal;
  };
  
  Object.defineProperty(target, propertyKey, {
    get: getter,
    set: setter,
  });
}

class User {
  @validate
  name: string;
  
  constructor(name: string) {
    this.name = name;
  }
}

// Parameter Decorator
function required(target: any, propertyKey: string, parameterIndex: number) {
  console.log(`Parameter at index ${parameterIndex} is required`);
}

class Service {
  greet(@required name: string) {
    return `Hello, ${name}`;
  }
}

// Accessor Decorator
function configurable(value: boolean) {
  return function (
    target: any,
    propertyKey: string,
    descriptor: PropertyDescriptor
  ) {
    descriptor.configurable = value;
  };
}

class Point {
  private _x: number;
  private _y: number;
  
  constructor(x: number, y: number) {
    this._x = x;
    this._y = y;
  }
  
  @configurable(false)
  get x() {
    return this._x;
  }
}

13. Advanced Types

// Conditional Types
type IsNumber<T> = T extends number ? true : false;
type Result1 = IsNumber<42>;    // true
type Result2 = IsNumber<"42">;  // false

// Infer Keyword
type UnpackArray<T> = T extends (infer U)[] ? U : T;
type StringType = UnpackArray<string[]>;     // string
type NumberType = UnpackArray<number>;       // number

// Mapped Types
type Readonly<T> = {
  readonly [P in keyof T]: T[P];
};

type Optional<T> = {
  [P in keyof T]?: T[P];
};

type Nullable<T> = {
  [P in keyof T]: T[P] | null;
};

// Template Literal Types
type World = "world";
type Greeting = `hello ${World}`;  // "hello world"

type EmailLocaleIDs = "welcome_email" | "email_heading";
type FooterLocaleIDs = "footer_title" | "footer_sendoff";
type AllLocaleIDs = `${EmailLocaleIDs | FooterLocaleIDs}_id`;

// Keyof Type Operator
type Point = { x: number; y: number };
type P = keyof Point;  // "x" | "y"

type Arrayish = { [n: number]: unknown };
type A = keyof Arrayish;  // number

// Typeof Type Operator
let s = "hello";
let n: typeof s;  // string

function f() {
  return { x: 10, y: 3 };
}
type F = typeof f;  // () => { x: number; y: number; }

// Indexed Access Types
type Person = { age: number; name: string; alive: boolean };
type Age = Person["age"];  // number
type I1 = Person["age" | "name"];  // string | number

// Conditional Types with Infer
type ReturnType<T> = T extends (...args: any[]) => infer R ? R : never;
type FuncReturnType = ReturnType<() => string>;  // string

// Distributive Conditional Types
type ToArray<T> = T extends any ? T[] : never;
type StrArrOrNumArr = ToArray<string | number>;  // string[] | number[]

14. Type Manipulation

// Creating Types from Values
const config = {
  host: "localhost",
  port: 3000,
  ssl: true,
};

// typeof type operator
type Config = typeof config;

// Index types
type ConfigKey = keyof Config;  // "host" | "port" | "ssl"
type HostType = Config["host"];  // string

// Mapped Types with Template Literals
type EventConfig<T extends string> = {
  [K in T as `on${Capitalize<K>}`]: (event: K) => void;
};
// Example: EventConfig<"click" | "hover">
// Result: { onClick: (event: "click") => void; onHover: (event: "hover") => void; }

// Recursive Types
type TreeNode<T> = {
  value: T;
  children?: TreeNode<T>[];
};

// Deep Partial
type DeepPartial<T> = {
  [P in keyof T]?: T[P] extends object ? DeepPartial<T[P]> : T[P];
};

// Deep Readonly
type DeepReadonly<T> = {
  readonly [P in keyof T]: T[P] extends object ? DeepReadonly<T[P]> : T[P];
};

// Branded Types
type Brand<T, B> = T & { __brand: B };
type USD = Brand<number, "USD">;
type EUR = Brand<number, "EUR">;

const usd = 10 as USD;
const eur = 10 as EUR;

function convertUSDtoEUR(usd: USD): EUR {
  return (usd * 0.85) as EUR;
}

// Flatten Array Type
type Flatten<T> = T extends any[] ? T[number] : T;
type Str = Flatten<string[]>;      // string
type Num = Flatten<number>;          // number

// Merge Types
type Merge<A, B> = {
  [K in keyof A | keyof B]: 
    K extends keyof A & keyof B ? A[K] | B[K] :
    K extends keyof A ? A[K] : 
    K extends keyof B ? B[K] : never;
};

15. Error Handling

// Custom Error Classes
class ValidationError extends Error {
  constructor(message: string, public field: string) {
    super(message);
    this.name = "ValidationError";
  }
}

class DatabaseError extends Error {
  constructor(message: string, public code: number) {
    super(message);
    this.name = "DatabaseError";
  }
}

// Error Handling with Types
async function fetchData(url: string): Promise<string> {
  try {
    const response = await fetch(url);
    if (!response.ok) {
      throw new Error(`HTTP error! status: ${response.status}`);
    }
    return await response.text();
  } catch (error) {
    if (error instanceof TypeError) {
      throw new Error("Network error occurred");
    }
    throw error; // Re-throw unknown errors
  }
}

// Type-Safe Error Handling
type Result<T, E = Error> = 
  | { success: true; data: T }
  | { success: false; error: E };

function divide(a: number, b: number): Result<number, string> {
  if (b === 0) {
    return { success: false, error: "Division by zero" };
  }
  return { success: true, data: a / b };
}

// Using the result
const result = divide(10, 0);
if (result.success) {
  console.log(result.data);
} else {
  console.error(result.error);
}

// Async Result Pattern
async function asyncOperation(): Promise<Result<string>> {
  try {
    const data = await fetchData("https://api.example.com");
    return { success: true, data };
  } catch (error) {
    return { 
      success: false, 
      error: error instanceof Error ? error : new Error(String(error))
    };
  }
}

// Assertion Functions
function assertIsString(value: unknown): asserts value is string {
  if (typeof value !== "string") {
    throw new Error("Not a string!");
  }
}

16. Configuration (tsconfig.json)

{
  "compilerOptions": {
    /* Basic Options */
    "target": "ES2020",                    // Target ECMAScript version
    "module": "commonjs",                  // Module system
    "lib": ["ES2020", "DOM"],             // Library files to include
    "outDir": "./dist",                    // Output directory
    "rootDir": "./src",                    // Source directory
    "strict": true,                        // Enable all strict checks
    
    /* Module Resolution */
    "moduleResolution": "node",            // Module resolution strategy
    "baseUrl": "./",                       // Base directory for resolution
    "paths": {                             // Path mapping
      "@app/*": ["src/*"],
      "@utils/*": ["src/utils/*"]
    },
    "esModuleInterop": true,               // ES module interop
    "allowSyntheticDefaultImports": true,  // Allow default imports
    
    /* Strict Type-Checking */
    "noImplicitAny": true,                 // Error on implicit any
    "strictNullChecks": true,              // Strict null checking
    "strictFunctionTypes": true,           // Strict function types
    "noImplicitThis": true,                // Error on implicit this
    "alwaysStrict": true,                  // Parse in strict mode
    
    /* Additional Checks */
    "noUnusedLocals": true,                // Error on unused locals
    "noUnusedParameters": true,            // Error on unused parameters
    "noImplicitReturns": true,             // Error on implicit returns
    "noFallthroughCasesInSwitch": true,   // Error on fallthrough
    
    /* Source Maps */
    "sourceMap": true,                      // Generate source maps
    "declaration": true,                    // Generate .d.ts files
    "declarationMap": true,                 // Generate declaration map
    
    /* Advanced */
    "skipLibCheck": true,                   // Skip type checking of .d.ts
    "forceConsistentCasingInFileNames": true,
    "resolveJsonModule": true,              // Allow importing JSON
    "isolatedModules": true                 // Transpile each file separately
  },
  "include": ["src/**/*"],
  "exclude": ["node_modules", "dist"],
  "extends": "./tsconfig.base.json"       // Extend from base config
}

17. Best Practices & Patterns

// 1. Use Discriminated Unions for State
type RequestState<T> = 
  | { status: "idle" }
  | { status: "loading" }
  | { status: "success"; data: T }
  | { status: "error"; error: Error };

// 2. Branded Types for Domain Types
type Email = Brand<string, "Email">;
type Password = Brand<string, "Password">;

function createEmail(email: string): Email {
  if (!email.includes("@")) throw new Error("Invalid email");
  return email as Email;
}

// 3. Builder Pattern with Types
class RequestBuilder {
  private url: string = "";
  private method: "GET" | "POST" = "GET";
  private headers: Record<string, string> = {};
  
  setUrl(url: string): this {
    this.url = url;
    return this;
  }
  
  setMethod(method: "GET" | "POST"): this {
    this.method = method;
    return this;
  }
  
  build(): Request {
    return new Request(this.url, {
      method: this.method,
      headers: this.headers,
    });
  }
}

// 4. Type-Safe Event Emitter
type EventMap = {
  click: { x: number; y: number };
  keypress: { key: string };
};

class TypedEventEmitter<T extends Record<string, any>> {
  private handlers = new Map<keyof T, Set<Function>>();
  
  on<K extends keyof T>(event: K, handler: (data: T[K]) => void): void {
    if (!this.handlers.has(event)) {
      this.handlers.set(event, new Set());
    }
    this.handlers.get(event)!.add(handler);
  }
  
  emit<K extends keyof T>(event: K, data: T[K]): void {
    this.handlers.get(event)?.forEach(handler => handler(data));
  }
}

// 5. Type-Safe Object Property Path
type Path<T, K extends keyof T = keyof T> = 
  K extends string
    ? T[K] extends object
      ? `${K}.${Path<T[K]>}` | K
      : K
    : never;

// 6. Constrained Identity Function
const createObj = <T extends Record<string, unknown>>(obj: T) => obj;
const person = createObj({
  name: "John",
  age: 30,
}); // Type is preserved exactly

// 7. Type-Safe Fluent Interface
class Query<T> {
  private filters: Array<(item: T) => boolean> = [];
  
  where(predicate: (item: T) => boolean): this {
    this.filters.push(predicate);
    return this;
  }
  
  execute(data: T[]): T[] {
    return data.filter(item => 
      this.filters.every(filter => filter(item))
    );
  }
}

Quick Reference

Common TypeScript Commands

# Install TypeScript
npm install -g typescript

# Compile TypeScript
tsc file.ts
tsc --watch file.ts
tsc --project tsconfig.json

# Initialize tsconfig
tsc --init

# Check types without compiling
tsc --noEmit

Useful Links

About

Master TypeScript with this comprehensive cheatsheet covering everything from basic types and interfaces to advanced generics, decorators, and utility types. Includes practical code examples, configuration setup, and best practices.

Topics

Resources

License

Code of conduct

Contributing

Security policy

Stars

Watchers

Forks

Releases

No releases published

Packages

 
 
 

Contributors

Generated from cheatnotes/cheatnotes