1.25 — TypeScript Essentials: Quick Revision
Compact cheat sheet. Print-friendly.
How to use this material (instructions)
- Skim before labs or interviews.
- Drill gaps — reopen
README.md then 1.25.a through 1.25.l.
- Practice —
1.25-Exercise-Questions.md.
- Polish answers —
1.25-Interview-Questions.md.
Core vocabulary
| Term | One-liner |
|---|
| TypeScript | Typed superset of JavaScript that compiles to plain JS |
| Type annotation | Explicit type label: let x: string |
| Type inference | TS automatically determines types from context |
| Compile time | When tsc checks types — before code runs |
tsc | TypeScript compiler — type-checks and emits JS |
tsconfig.json | Configuration file for the TS compiler |
| Declaration file | .d.ts — type definitions without implementation |
Basic types
| Type | Example | Notes |
|---|
string | "hello" | Text |
number | 42, 3.14 | All numbers (no int/float split) |
boolean | true | Logical |
any | let x: any | Opts out of checking (avoid!) |
unknown | let x: unknown | Safe any — must narrow first |
void | (): void | Function returns nothing |
null | null | Intentional absence |
undefined | undefined | Not assigned |
never | (): never | Never returns (throws/infinite loop) |
bigint | 42n | Large integers |
Type annotation syntax
let name: string = "Alice";
let age: number = 30;
function greet(name: string): string { return `Hi, ${name}`; }
const add = (a: number, b: number): number => a + b;
let names: string[] = ["Alice", "Bob"];
let nums: Array<number> = [1, 2, 3];
let pair: [string, number] = ["Alice", 30];
let user: { name: string; age: number } = { name: "Alice", age: 30 };
Interface vs type
interface User {
id: number;
name: string;
email?: string;
readonly role: string;
}
type ID = string | number;
type Status = "active" | "inactive";
type Pair = [string, number];
type Callback = (data: string) => void;
| Feature | interface | type |
|---|
| Object shape | Yes | Yes |
| Extends | extends | & |
| Declaration merging | Yes | No |
implements | Yes | No |
| Unions | No | Yes |
| Tuples | No | Yes |
| Primitives | No | Yes |
Default: interface for objects, type for everything else.
Union and intersection
let id: string | number;
type Admin = User & { permissions: string[] };
type Shape =
| { type: "circle"; radius: number }
| { type: "square"; side: number };
Type narrowing
if (typeof x === "string") { x.toUpperCase(); }
if (error instanceof Error) { error.message; }
if ("fly" in animal) { animal.fly(); }
switch (shape.type) {
case "circle": shape.radius; break;
case "square": shape.side; break;
}
function isCat(a: Cat | Dog): a is Cat { return "meow" in a; }
Generics
function identity<T>(value: T): T { return value; }
interface Box<T> { value: T; }
function logLength<T extends { length: number }>(x: T): void {
console.log(x.length);
}
function pair<A, B>(a: A, b: B): [A, B] { return [a, b]; }
interface Container<T = string> { value: T; }
Utility types
| Utility | What it does | Example |
|---|
Partial<T> | All props optional | Partial<User> |
Required<T> | All props required | Required<Config> |
Pick<T, K> | Keep only K | Pick<User, "id" | "name"> |
Omit<T, K> | Remove K | Omit<User, "password"> |
Record<K, V> | Object from key/value | Record<string, number> |
Readonly<T> | All props readonly | Readonly<State> |
ReturnType<F> | Function return type | ReturnType<typeof fn> |
Parameters<F> | Function param types | Parameters<typeof fn> |
NonNullable<T> | Remove null/undefined | NonNullable<string | null> |
Exclude<T, U> | Remove from union | Exclude<"a"|"b"|"c", "a"> |
Extract<T, U> | Keep in union | Extract<"a"|"b"|"c", "a"> |
keyof and mapped types
type UserKeys = keyof User;
function get<T, K extends keyof T>(obj: T, key: K): T[K] {
return obj[key];
}
type Stringify<T> = { [K in keyof T]: string };
type Flags<T> = { [K in keyof T]: boolean };
Enums and literal types
enum Status { Active = "ACTIVE", Inactive = "INACTIVE" }
type Status = "active" | "inactive";
type HttpMethod = "GET" | "POST" | "PUT" | "DELETE";
const config = { port: 3000, host: "localhost" } as const;
tsconfig.json key options
| Option | Purpose | Recommended |
|---|
target | JS output version | "ES2020" |
module | Module system | "commonjs" (Node) or "ESNext" (bundler) |
strict | All strict checks | true (always) |
outDir | Output directory | "./dist" |
rootDir | Source directory | "./src" |
lib | Built-in type libs | ["ES2020", "DOM"] |
jsx | JSX handling | "react-jsx" |
moduleResolution | Import resolution | "bundler" or "node" |
esModuleInterop | Default import fix | true |
skipLibCheck | Skip .d.ts checking | true |
noEmit | Type-check only | true (when bundler compiles) |
declaration | Generate .d.ts | true (for libraries) |
sourceMap | Generate .js.map | true (for debugging) |
include | Files to compile | ["src/**/*"] |
exclude | Files to skip | ["node_modules", "dist"] |
Compiler commands
npx tsc
npx tsc hello.ts
npx tsc --watch
npx tsc --noEmit
npx tsc --init
npx tsc --noEmitOnError
npx tsc --build
Running TypeScript
| Tool | Type-checks? | Speed | Use case |
|---|
tsc | Yes | Moderate | Production build, CI |
tsc --noEmit | Yes | Moderate | Type checking only |
ts-node | Yes (default) | Slow | Scripts, REPL |
tsx | No | Fast | Development |
| Vite/esbuild | No | Very fast | Bundled apps |
Dev workflow: tsx watch for running + tsc --noEmit --watch for type checking.
ESLint + Prettier
npm install -D eslint @typescript-eslint/parser @typescript-eslint/eslint-plugin
npm install -D prettier eslint-config-prettier
npm install -D husky lint-staged
ESLint = code quality (bugs, patterns).
Prettier = formatting (whitespace, quotes).
eslint-config-prettier = disables ESLint formatting rules that conflict with Prettier.
Key TS ESLint rules
| Rule | Purpose |
|---|
no-explicit-any | Ban any usage |
no-unused-vars | Catch dead code |
no-floating-promises | Unhandled promises |
consistent-type-imports | Use import type |
CI pipeline order
1. typecheck → tsc --noEmit
2. lint → eslint src/
3. format → prettier --check src/
4. test → vitest run
5. build → vite build (or tsc)
Common patterns
function find(id: number): User | null { }
const name = user?.profile?.name ?? "Anonymous";
const input = document.getElementById("email") as HTMLInputElement;
function handle(action: Action): State {
switch (action.type) {
case "increment": return state + action.amount;
case "reset": return 0;
default: const _: never = action; return _;
}
}
async function fetchData<T>(url: string): Promise<T> {
const res = await fetch(url);
return res.json();
}
const users = await fetchData<User[]>("/api/users");
Master workflow
- Define types — interfaces, type aliases for data shapes.
- Write signatures — function inputs/outputs (types-first).
- Implement — let autocomplete and errors guide you.
- Refactor — compiler flags every breakage.
- Lint + format — ESLint + Prettier on save.
- Commit — husky + lint-staged enforce quality.
- CI — typecheck + lint + format + test + build.
End of 1.25 quick revision.