CTCaliberTek
Cheat Sheets

TypeScript Cheat Sheet: Types, Interfaces, Generics, and Utility Types

Published October 5, 2026·Updated October 29, 2026·6 min read
Like SaveLog in to like, save, and track progress.

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>  // string

Step 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

Comments

Log in or create a free account to join the discussion.

  • No comments yet. Be the first to comment.