Basic Types
let s: string = "hi";
let n: number = 42;
let b: boolean = true;
let big: bigint = 10n;
let arr: number[] = [1, 2, 3];
let arr2: Array<string> = ["a"];
let tup: [string, number] = ["x", 1];
enum Role { User, Admin }
type Dir = "up" | "down"; // prefer literal unions
let anyVal: any; // avoid: no checks
let unk: unknown; // safe: must narrow
function fail(): never { throw new Error(); }
function log(): void {}
Interfaces & Types
interface User {
id: number;
name?: string; // optional
readonly created: Date; // immutable
}
interface Admin extends User { role: "admin"; }
type Point = { x: number; y: number };
type ID = string | number; // only type
type Fn = (a: number) => string;
const u = { id: 1, created: new Date() } as const;
interface vs type
Use interface for object shapes (supports merging/extends); use type for unions, tuples, and primitives.
Unions, Intersections & Generics
Unions & Intersections
type Status = "loading" | "ok" | "error"; // union
type Both = { a: 1 } & { b: 2 }; // intersection
Generics
function id<T>(x: T): T { return x; }
function first<T>(a: T[]): T | undefined { return a[0]; }
class Box<T> { constructor(public value: T) {} }
const b = new Box<string>("hi");
// Constraints
function len<T extends { length: number }>(x: T) { return x.length; }
function prop<T, K extends keyof T>(o: T, k: K): T[K] { return o[k]; }
Narrowing & Guards
function f(x: string | number) {
if (typeof x === "string") x.trim(); // typeof
else x.toFixed(2);
}
if (val instanceof Date) {} // instanceof
if ("swim" in pet) {} // in operator
// Discriminated union + exhaustiveness
type Shape =
| { kind: "circle"; r: number }
| { kind: "square"; s: number };
function area(x: Shape) {
switch (x.kind) {
case "circle": return Math.PI * x.r ** 2;
case "square": return x.s ** 2;
default: const _: never = x; return _;
}
}
// Type guard + assertion function
function isStr(x: unknown): x is string { return typeof x === "string"; }
function assert<T>(v: T | null): asserts v is T {
if (v == null) throw new Error();
}
Utility Types
| Utility | Effect |
|---|---|
Partial<T> | All props optional |
Required<T> | All props required |
Readonly<T> | All props readonly |
Pick<T, K> | Keep only keys K |
Omit<T, K> | Remove keys K |
Record<K, V> | Map of K to V |
ReturnType<F> | Function return type |
Parameters<F> | Tuple of param types |
Awaited<T> | Unwrap a Promise |
NonNullable<T> | Remove null/undefined |
type Draft = Partial<User>;
type Pub = Omit<User, "email">;
type ById = Record<number, User>;
type R = ReturnType<typeof getUser>;
Mapped, Conditional & keyof
// keyof / typeof / indexed access
type Keys = keyof User; // "id" | "name" | ...
type Name = User["name"]; // string
type S = typeof someValue;
// Mapped type (with modifier + key remap)
type Optional<T> = { [K in keyof T]?: T[K] };
type Mutable<T> = { -readonly [K in keyof T]: T[K] };
type Getters<T> = {
[K in keyof T as `get${Capitalize<string & K>}`]: () => T[K];
};
// Conditional + infer
type IsStr<T> = T extends string ? true : false;
type ElemOf<T> = T extends (infer U)[] ? U : never;
type Ret<F> = F extends (...a: any[]) => infer R ? R : never;
// Template literal
type Variant = `${"light" | "dark"}-${"red" | "blue"}`;
Classes
interface Speaker { speak(): string; }
abstract class Animal implements Speaker {
constructor(protected readonly name: string) {} // param property
abstract speak(): string;
}
class Dog extends Animal {
#tricks = 0; // true private (runtime)
private secret = 1; // TS-only private
speak() { return `${this.name} woof`; }
static create(n: string) { return new Dog(n); }
}
tsconfig Flags
{
"compilerOptions": {
"target": "ES2022",
"module": "ESNext",
"moduleResolution": "bundler",
"strict": true, // enable all strict checks
"noImplicitAny": true,
"strictNullChecks": true,
"noUncheckedIndexedAccess": true,
"esModuleInterop": true,
"skipLibCheck": true,
"noEmit": true
}
}
Modules & Tooling
export interface User { id: number; }
import { User } from "./user";
import type { User } from "./user"; // erased at build
# Type-check only
npx tsc --noEmit
npx tsc --watch
# Run .ts directly
npx tsx src/index.ts
# Lint
npx eslint . --ext .ts,.tsx