Values and Types in TypeScript
Understand the core type system and common value categories.
Primitives
- string, number, boolean
- bigint: integers beyond 2^53-1:
123n - symbol: unique identifiers
- null and undefined: enable
strictNullChecksto model absence precisely
let s: string = "hi";
let n: number = 42;
let ok: boolean = true;
let big: bigint = 9007199254740993n;
let sym: symbol = Symbol("id");
any vs unknown vs never vs void
- any: opt-out of type safety; avoid except at boundaries
- unknown: like
anybut forces narrowing before use - never: a function that never returns (throws or infinite loop)
- void: absence of a return value
function fail(msg: string): never { throw new Error(msg); }
function log(x: unknown): void {
if (typeof x === "string") console.log(x.toUpperCase());
}
Objects, arrays, tuples
const user: { id: number; name: string } = { id: 1, name: "Ada" };
const nums: number[] = [1, 2, 3];
const pair: [string, number] = ["age", 42];
Use readonly arrays and tuples when order/length is fixed.
Literal types and widening
let dir: "up" | "down";
dir = "up"; // ok
// dir = "left"; // error
Avoid unwanted widening by using as const or satisfies.
const cfg = { mode: "prod", retries: 3 } as const; // literal inference
Template literal types
type EventName = `on${"Click" | "Hover"}`; // "onClick" | "onHover"
Structural typing
Compatibility is based on shape, not nominal identity.
interface Named { name: string }
function printName(x: Named) { console.log(x.name); }
printName({ name: "Lin" }); // ok (extra props allowed at call sites)
Narrowing basics
Control-flow analysis refines types.
function len(x: string | string[]) {
return typeof x === "string" ? x.length : x.length;
}
Summary
- Prefer
unknownoverany; use literal types for exact values - Arrays/tuples model lists and fixed positions; structural typing favors flexibility