Reference · core type vocabulary

Core type vocabulary — decoder

The six building blocks of Module 1 on one page: type vs interface, the loose object types, literals/unions vs enum, keyof/typeof/ indexed access, the utility-type catalog, tuples vs arrays, and never. Pin it; print it.

type vs interface (1.1)

capabilityinterfacetype
object / class shapeyesyes
union, tuple, primitive aliasnoyes
declaration mergingyesno
extendextends& intersection
Tell: a union/tuple must be a type. A name declared twice that both survive is an interface (they merge). For a plain object, either works — reach for interface on shapes, type on everything else.

object vs {} vs Object (1.1)

you see…meansaccepts
objectany non-primitive (lowercase)objects/arrays/fns — not primitives
{}anything except null/undefinedalmost everything, incl. 42, "hi"
Objectglobal wrapper interface (capital O)nearly everything — avoid; a smell
let b: object = 42;   // ERR — 42 is primitive, not an object
let c: {} = 42;       // OK  — {} = non-nullish, and 42 qualifies
let d: {} = null;     // ERR — null is the one thing {} rejects

Literals, unions vs enum (1.2)

formreads as
"click"literal type — the type whose only value is "click"
"a" | "b" | "c"union — a closed set; exactly one of these, nothing else
<T extends string>constraint that preserves the literal instead of widening to string
String-literal union vs enum: the union is pure type info — erased, pass the bare string. An enum emits a runtime object you must import (Dir.Up). Prefer the union for lightness; that’s why most modern code uses it.
function test1<T extends string>(v: T): T { return v; }
const r1 = test1("hello");   // "hello"  — literal kept
const r2 = ((v: string) => v)("hello"); // string  — widened

keyof / typeof / indexed access (1.3)

operatorworldreads as
typeof x === "…"valueruntime tag check
typeof valuetypelift a value into its static type
keyof Ttypeunion of T’s key names
keyof typeof Xtypevalue → type → union of its keys
T[K]typeindexed access — the type at key K
function getProperty<T, K extends keyof T>(obj: T, key: K) { return obj[key]; }

type EventMap = { "click": { x: number }; "keydown": { key: string } };
function on<K extends keyof EventMap>(t: K, cb: (e: EventMap[K]) => void) {}  // EventMap[K] = exact event

Utility-type catalog (1.4)

utilityreads asoperates on
Partial<T>every property optional (top level)object type
Record<K,V>object with keys K, values Vkey + value type
Pick<T,K>keep only keys Kobject type
Omit<T,K>drop properties Kobject type
Exclude<U,X>remove members Xunion
Extract<U,X>keep members assignable to Xunion
Omit (object → drop properties) vs Exclude (union → drop members) — if the first arg is { … } it’s Omit; if it’s A | B it’s Exclude. Partial is shallow; DeepPartial recurses.
type DeepPartial<T> = { [P in keyof T]?: T[P] extends object ? DeepPartial<T[P]> : T[P]; };
Partial<Record<Exclude<PluralRule, "other">, string>>  // read inside-out: filter → build → loosen

Tuples vs arrays (1.5)

array T[]tuple [A, B]
lengthvariable / openfixed
element typesall the sameone per position
position matters?noyes
string[] = any-length list of strings · [string] = tuple of exactly one. A parameter list is a tuple: ...args: [number, string] keeps each position’s type; ...args: any[] flattens and loses them.

The never type (1.6)

faceworldbehavior
exhaustivenessvalueconst _x: never = shape fails if a case is unhandled
key droptypekey remapped to never vanishes (string | never = string)
narrowing dead-enderror“not assignable to never” = slot narrowed to nothing
type PublicUser = { [K in keyof User as K extends "password" ? never : K]: User[K] };
// "password" → never → filtered out of the result

The 3-second checks

  1. type or interface? Union/tuple → type. Merges on repeat → interface.
  2. which typeof? In a === → value/runtime · after : → value-to-type.
  3. Omit or Exclude? First arg { … }Omit · first arg A | BExclude.
  4. tuple or array? Several types in order → tuple · one type + [] → array.
  5. which never? Assigned to → guard · produced by a key → drop · in an error → dead-end.