Skip to content

Cheat sheet · TypeScript

TypeScript Cheat Sheet

A scannable TypeScript reference covering basic types, interfaces and type aliases, arrays and tuples, functions, union and literal types, generics, enums, type narrowing, and the built-in utility types.

A cheat sheet is for the thing you have understood once and cannot quite remember the shape of. It is written to be scanned, so the common cases come first. Starting from nothing? The TypeScript exercises are the right first step; come back here once the syntax is something you are recalling rather than meeting. Looking for another language? See every cheat sheet.

This page is a fast-scanning reference for TypeScript syntax you'll reach for constantly - not a tutorial. Each section is a self-contained group of snippets, so jump straight to the part you need. Where a line's real, printed output isn't obvious from reading it, a comment after it (or a text block underneath) shows exactly what the compiler or the running program produces.

Basic Types

TypeScript
let name: string = "Priya";     // annotated
let age = 27;                     // inferred as number
let gpa = 3.85;                     // inferred as number
let isActive = true;                  // inferred as boolean

typeof age;                             // "number"

Converting between types is done with Number(), String(), Boolean(), and the older parseInt() / parseFloat(). parseInt() stops at the first character that isn't part of a whole number, rather than rejecting the text outright:

TypeScript
Number("42");            // 42
String(17);                 // "17"
Boolean(0);                    // false
parseInt("3.9", 10);              // 3 — parses only the integer part
parseFloat("2.5");                    // 2.5

Type Annotations vs Inference

A variable declared with an initial value doesn't need an annotation - TypeScript infers the type from the value and enforces it exactly as strictly as a written one:

TypeScript
let elevation = 1795;     // inferred as number, same protection as writing `: number` yourself

let total: number;           // no initializer here, so the annotation is what fixes the type
total = 10 + 25;
TypeScript
let age: number = 30;
let label: string = "thirty";
age = label;
Output
main.ts(3,1): error TS2322: Type 'string' is not assignable to type 'number'.

Interfaces & Type Aliases

TypeScript
interface Point {
  x: number;
  y: number;
}

type Coordinate = {
  x: number;
  y: number;
};

const a: Point = { x: 1, y: 2 };
const b: Coordinate = a;      // same shape as Point, so this is allowed — structural typing

? marks a property optional; readonly blocks reassignment after the object is created:

TypeScript
interface Product {
  name: string;
  price: number;
  readonly sku: string;
  discount?: number;
}

A type alias can also combine shapes with | (union) and & (intersection), which interface can't do directly:

TypeScript
type Id = string | number;                    // union
type Named = { name: string };
type Aged = { age: number };
type Person = Named & Aged;                      // intersection — has both name and age

const p: Person = { name: "Kai", age: 40 };

Arrays & Tuples

Type[] and Array<Type> mean the same thing. A tuple, [Type1, Type2], is different: it has a fixed length, and each position keeps its own type.

TypeScript
const scores: number[] = [92, 88, 79];
const names: Array<string> = ["Ana", "Ben"];

scores.push(100);         // ok
names.push("Chi");          // ok

const point: [number, number] = [3, 4];
const [x, y] = point;         // destructuring — x = 3, y = 4

point[0] = 10;                  // ok — a tuple isn't automatically read-only

Functions

TypeScript
function add(a: number, b: number): number {
  return a + b;
}

const multiply = (a: number, b: number): number => a * b;    // arrow function

function greet(name: string, greeting = "Hello"): string {     // default parameter
  return `${greeting}, ${name}!`;
}

function shout(text: string, volume?: number): string {          // optional parameter — type is number | undefined
  return volume !== undefined && volume > 5 ? text.toUpperCase() : text;
}

add(2, 3);               // 5
multiply(2, 3);             // 6
greet("Mei");                  // "Hello, Mei!"
greet("Mei", "Hey");              // "Hey, Mei!"
shout("careful", 8);                 // "CAREFUL"

Every parameter needs a type - either written directly or, for an optional or default parameter, inferred from its default value. There's no fallback to "anything goes" the way an untyped JavaScript parameter works.

Union & Literal Types

TypeScript
let id: string | number = "A1";
id = 42;    // ok — still matches the union

A literal type is a type with exactly one legal value; a union of literal types describes a fixed set of options, and anything outside that set is rejected at compile time - even a value of the right general type:

TypeScript
type Direction = "up" | "down" | "left" | "right";
let move: Direction = "up";
move = "sideways";
Output
main.ts(3,1): error TS2322: Type '"sideways"' is not assignable to type 'Direction'.

Generics

A generic type parameter, <T>, is a placeholder for "whatever type this call is using" - inferred fresh per call, and checked exactly like a concrete type would be:

TypeScript
function identity<T>(value: T): T {
  return value;
}

identity<string>("hello");      // "hello", T given explicitly
identity(42);                     // 42, T inferred as number

function firstElement<T>(items: T[]): T {
  return items[0];
}

firstElement([10, 20, 30]);         // 10

function pair<A, B>(first: A, second: B): [A, B] {
  return [first, second];
}

console.log(pair("age", 30));
Output
[ 'age', 30 ]

<T extends ...> constrains what a generic type parameter must have, without pinning it to one concrete type:

TypeScript
function longest<T extends { length: number }>(a: T, b: T): T {
  return a.length >= b.length ? a : b;
}

longest("hello", "hi");      // "hello"

Enums

TypeScript
enum Compass {
  Up,
  Down,
  Left,
  Right,
}

Compass.Up;         // 0
Compass.Right;         // 3

enum Status {
  Active = "ACTIVE",
  Inactive = "INACTIVE",
}

Status.Active;             // "ACTIVE"

An enum-typed variable only accepts the enum's own members - not even the exact matching underlying string is assignable directly. as const locks an object or array literal down to its most specific, read-only type:

TypeScript
const config = { mode: "fast", retries: 3 } as const;    // every property becomes readonly and literal-typed

config.mode = "slow";
Output
main.ts(3,8): error TS2540: Cannot assign to 'mode' because it is a read-only property.

Type Narrowing

TypeScript
function describe(value: string | number): string {
  if (typeof value === "string") {
    return value.toUpperCase();
  }
  return value.toFixed(1);
}

describe("hi");        // "HI"
describe(3);               // "3.0"

A function whose return type is written value is Type (instead of a plain boolean) narrows the argument's type for whoever calls it - this is a custom type guard:

TypeScript
function isStringArray(value: unknown): value is string[] {
  return Array.isArray(value) && value.every((item) => typeof item === "string");
}

function shoutAll(value: unknown): string[] {
  return isStringArray(value) ? value.map((s) => s.toUpperCase()) : [];
}

console.log(shoutAll(["a", "b"]));
console.log(shoutAll(42));
Output
[ 'A', 'B' ]
[]

Utility Types

These build a new type out of an existing one. They exist purely for the compiler - there's no value attached to any of them, so there's nothing to console.log and no runtime output to show, only a description of the shape each one produces.

TypeScript
interface User {
  id: number;
  name: string;
  email: string;
}

type UserDraft = Partial<User>;                 // every property becomes optional: { id?: number; name?: string; email?: string }
type UserPreview = Pick<User, "id" | "name">;      // only the listed properties: { id: number; name: string }
type PublicUser = Omit<User, "email">;                // every property except the listed ones: { id: number; name: string }
type Scoreboard = Record<string, number>;                // an object type with string keys and number values

Partial is the type you reach for when updating an object one field at a time; Pick and Omit are mirror images of each other for narrowing an interface down to a subset of its own properties; Record builds a dictionary-shaped type from a key type and a value type.

Try any snippet with your own values in the TypeScript playground.