TypeScript Cheat Sheet
A searchable reference of everyday TypeScript syntax and what each piece does.
| Snippet | What it does |
|---|---|
let count: number = 5 | Add a type annotation so the variable can only hold that type. |
let title: string = "hi" | The string type holds text values. |
let total: number = 42 | The number type covers integers and floats alike. |
let active: boolean = true | The boolean type holds only true or false. |
let data: any | The any type opts out of type checking; avoid it when you can. |
let input: unknown | A safer any: you must narrow the value before using it. |
function fail(): never | The never type marks a function that never returns, such as one that always throws. |
function log(msg: string): void | The void type marks a function that returns no useful value. |
let ids: number[] | An array of numbers using the shorthand array syntax. |
let ids: Array<number> | The same array written with the generic Array form. |
let pair: [string, number] | A tuple: a fixed-length array where each position has its own type. |
let dir: "up" | "down" | A literal type: the value must be one of the exact strings listed. |
enum Role { Admin, User } | An enum names a fixed set of related constants. |
type ID = string | A type alias gives a name to any type so you can reuse it. |
interface User { name: string } | Describe the shape of an object with an interface. |
interface User { age?: number } | A question mark marks an optional property that may be omitted. |
interface Point { readonly x: number } | A readonly property can be set once but not reassigned later. |
interface Dict { [key: string]: number } | An index signature allows any string key mapping to a number. |
interface Admin extends User { level: number } | One interface can extend another to inherit its members. |
interface C extends A, B {} | An interface can extend several others at once. |
interface Add { (a: number, b: number): number } | A call signature describes an object that can be called like a function. |
type Point = { x: number; y: number } | A type alias can describe an object shape much like an interface. |
function greet(name: string): void | Annotate each parameter so callers pass the right types. |
function square(n: number): number | Annotate the return type after the parameter list. |
function log(msg: string, level?: string) | An optional parameter marked with ? may be left out by the caller. |
function inc(x: number, step = 1) | A default value is used when the caller omits that argument. |
function sum(...nums: number[]): number | A rest parameter gathers any remaining arguments into an array. |
function cmd(x: string): string; | Overload signatures list several call shapes above one implementation. |
function first<T>(arr: T[]): T | undefined | A generic function works for any element type T you pass in. |
const area = (r: number): number => r * r | A typed arrow function annotates its parameters and return type. |
type Handler = (e: string) => void | A function type alias describes the signature a callback must match. |
function wrap<T>(value: T): T[] | The type parameter T is a placeholder filled in at each call. |
function longest<T extends { length: number }>(a: T, b: T): T | A constraint with extends limits T to types that have a length. |
class Box<T = string> {} | A default type parameter is used when the caller supplies none. |
interface Container<T> { items: T[] } | A generic interface is parameterized by the type it stores. |
type UserKeys = keyof User | The keyof operator produces a union of an object type property names. |
type Cfg = typeof config | The typeof operator reads the type of an existing value. |
function prop<T, K extends keyof T>(o: T, k: K): T[K] | Combine keyof with indexed access to return the exact property type. |
type Pair<T> = [T, T] | A generic type alias reuses one shape across many element types. |
type Result = string | number | A union type allows a value to be any one of several types. |
type Full = Draggable & Resizable | An intersection type combines several types into one that has all members. |
if (typeof x === "string") {} | A typeof check narrows a union to one branch inside the block. |
if ("swim" in pet) {} | The in operator narrows by testing whether a property exists. |
function isFish(p: Pet): p is Fish | A user-defined type guard tells the compiler what a true result proves. |
type Shape = { kind: "circle"; r: number } | { kind: "square"; s: number } | A discriminated union uses a shared literal field to tell the members apart. |
type IsArray<T> = T extends any[] ? true : false | A conditional type picks one of two types based on an extends test. |
type Optional<T> = { [K in keyof T]?: T[K] } | A mapped type builds a new type by looping over each key of another. |
const config = { mode: "dark" } as const | The as const assertion freezes a value into its narrowest readonly type. |
const palette = { red: "#f00" } satisfies Record<string, string> | satisfies checks a value against a type while keeping its precise inferred type. |
"strict": true | The strict tsconfig flag turns on the full set of strong type checks. |
"noImplicitAny": true | Report an error when a value would otherwise fall back to the any type. |
"strictNullChecks": true | Make null and undefined separate types you must handle explicitly. |
const el = input as HTMLElement | An as assertion tells the compiler to treat a value as a given type. |
const s = <string>data | The angle-bracket form of a type assertion; avoid it in .tsx files. |
const el = document.getElementById("app")! | A non-null assertion promises the value is not null or undefined. |
declare const VERSION: string | The declare keyword describes a value that exists at runtime elsewhere. |
declare module "*.svg" {} | Declare an ambient module so imports of that pattern type-check. |
import type { User } from "./types" | A type-only import is erased at build time and carries no runtime code. |
No snippets match your search.
Runs entirely in your browser. Nothing you type is sent anywhere; open DevTools and watch the Network tab to verify zero requests.
What this tool does
This is a searchable quick reference for the TypeScript syntax you reach for every day, from basic type annotations and interfaces to functions, generics, advanced type operators, and compiler settings. Each row pairs a short snippet with a plain-English note on what it does. Type in the filter box to search across both columns, or tap a category button to focus on one topic. The whole list is built into the page, so it works offline and sends nothing anywhere.
How to use it
Start typing in the Filter box. Entering keyof jumps
to the operator that lists the property names of an object type; entering union
or guard surfaces the narrowing patterns; entering interface
shows every way to describe an object shape. The category buttons
(Basics, Interfaces, Functions, Generics, Advanced, Config) narrow the table to one
topic and combine with the text filter, so you can pick Generics and type
extends to zero in on constraints. Clear the box to see the full sheet
again.
Common use cases
- Recalling the exact syntax for a feature you use rarely, like a mapped type or a discriminated union.
- Checking the difference between
unknownandanybefore you annotate a value. - Looking up how to write a generic function with a constraint using
extends. - Reminding yourself which compiler flags, such as
strict, turn on stronger checks. - Reviewing core TypeScript syntax before an interview or a new project.
Common pitfalls
- Reaching for any. The
anytype silences the checker and lets runtime errors through. Preferunknownand narrow the value, so the safety net stays in place. - Overusing non-null assertions. The trailing
!promises a value is present without proving it. If that promise is wrong you get a runtime crash, so narrow with a real check when you can. - Confusing type assertions with conversions. An
asassertion only changes how the compiler views a value; it does not convert data at runtime, so asserting the wrong type just hides a bug. - Forgetting the discriminant. A union of object shapes is far easier
to narrow when each member shares a literal tag field like
kind. Without it, the compiler cannot tell the branches apart cleanly.
Frequently asked questions
- What is the difference between type and interface in TypeScript?
- Both can describe the shape of an object, and for most object types they are interchangeable. Interfaces can be reopened and merged across declarations and are often preferred for public object shapes, while a type alias can also name unions, intersections, tuples, primitives, and mapped or conditional types that an interface cannot express. A common rule of thumb is to reach for interface when describing an object or class contract and for type when you need those other shapes.
- What is a union type?
- A union type says a value may be any one of several types, written with a vertical bar as in string | number. Before you use the value in a type-specific way you usually narrow it with a check such as typeof, an in test, or a custom type guard, and inside that branch the compiler knows the more specific type. Unions of string literals, such as "up" | "down", are a simple way to model a fixed set of allowed values.
- What are generics in TypeScript?
- Generics let you write a function, class, or type that works over many types while keeping the relationship between them. A type parameter such as T acts as a placeholder that is filled in at each use, so a function typed as first<T>(arr: T[]): T returns the same element type it received instead of a vague any. You can constrain a parameter with extends to require certain members, and give it a default to use when none is supplied.
- What does keyof do in TypeScript?
- The keyof operator takes an object type and produces a union of its property names as string literal types. For an interface with name and age fields, keyof yields "name" | "age". It is most useful with generics: a function typed as prop<T, K extends keyof T>(o: T, k: K): T[K] can only be called with keys that actually exist on the object, and it returns the exact type of that property.
- What is the difference between unknown and any?
- Both can hold a value of any type, but they behave very differently. With any the compiler stops checking, so you can call or access anything on it and errors slip through to runtime. With unknown the compiler forces you to narrow the value with a check or an assertion before you can use it, which keeps the safety net in place. Prefer unknown for values whose type you do not yet know, such as parsed JSON or caught errors.
- Does this cheat sheet send anything to a server?
- No. The entire syntax list is baked into the page and every search and filter runs in your browser with JavaScript, so nothing you type is transmitted anywhere. Open your browser DevTools and watch the Network tab while you search to confirm there are zero requests.
Cite this tool
For academic, journalistic, or technical references. Pick a format:
Citations use 2026 as the publication year. Access date is left as a fillable placeholder where the citation style expects one.