Standard library
TypeScript does not have a standard library of its own — the runtime library is JavaScript’s, accessed through TypeScript’s lib.d.ts files describing the built-in globals. The conventional ECMAScript built-ins are: Object, Array, String, Number, Boolean, Date, RegExp, Math, JSON, Promise, Map, Set, WeakMap, WeakSet, Error and its subclasses, Symbol, Proxy, Reflect, and the Intl namespace for internationalisation. Browser environments add the DOM (document, window, Element, etc.) and Web APIs (fetch, Blob, URL, FormData, etc.). Node.js adds substantial APIs (fs, path, os, process, etc.). The combination — JavaScript’s substantial built-in globals plus the platform-specific surface — is the substance of TypeScript’s runtime library.
This tour points out the principal globals and APIs.
Object
The conventional object operations:
Object.keys(obj); // ["a", "b", ...]
Object.values(obj); // [1, 2, ...]
Object.entries(obj); // [["a", 1], ...]
Object.assign(target, source1, source2); // shallow merge
Object.freeze(obj); // shallow immutable
Object.isFrozen(obj);
Object.fromEntries(entries); // [["a", 1]] → { a: 1 }
Object.create(proto); // create with prototype
Object.getPrototypeOf(obj);
Object.setPrototypeOf(obj, proto);
Object.defineProperty(obj, "key", { value, writable, enumerable, configurable });
Object.getOwnPropertyDescriptor(obj, "key");
Object.hasOwn(obj, "key"); // ES2022; preferred over hasOwnProperty
The Object.fromEntries and Object.entries admit substantial transformation patterns:
const transformed = Object.fromEntries(
Object.entries(obj).map(([k, v]) => [k, transform(v)]),
);
const filtered = Object.fromEntries(
Object.entries(obj).filter(([k, v]) => v !== null),
);
Array
The principal array operations are treated in Loops and Data structures.
The static methods:
Array.from(iterable); // from iterable
Array.from({ length: 10 }, (_, i) => i); // [0, 1, ..., 9]
Array.from("abc"); // ["a", "b", "c"]
Array.of(1, 2, 3); // [1, 2, 3]
Array.isArray(value);
// Modern (ES2023):
arr.toSorted((a, b) => a - b); // non-mutating sort
arr.toReversed(); // non-mutating reverse
arr.toSpliced(1, 1); // non-mutating splice
arr.with(1, 99); // non-mutating set at index
The to* non-mutating variants admit immutable updates without spread.
String
The principal string operations are treated in Strings.
The static methods:
String.raw`literal\nwith\tno escapes`; // raw string from template
String.fromCharCode(65); // "A"
String.fromCodePoint(0x1F600); // "😀"
Number
Number.MAX_SAFE_INTEGER; // 2^53 - 1
Number.MIN_SAFE_INTEGER;
Number.EPSILON; // smallest distinguishable difference
Number.MAX_VALUE;
Number.MIN_VALUE;
Number.POSITIVE_INFINITY;
Number.NEGATIVE_INFINITY;
Number.NaN;
Number.isInteger(value);
Number.isSafeInteger(value);
Number.isFinite(value);
Number.isNaN(value); // strict; preferred over global isNaN
Number.parseInt("42", 10);
Number.parseFloat("3.14");
const n = 3.14159;
n.toFixed(2); // "3.14"
n.toPrecision(4); // "3.142"
n.toExponential(2); // "3.14e+0"
n.toString(16); // base-16 string
Math
Math.PI;
Math.E;
Math.LN2;
Math.LN10;
Math.LOG2E;
Math.LOG10E;
Math.SQRT2;
Math.abs(-5); // 5
Math.ceil(3.1); // 4
Math.floor(3.9); // 3
Math.round(3.5); // 4
Math.trunc(3.9); // 3 (toward zero)
Math.sign(-5); // -1
Math.max(1, 2, 3); // 3
Math.min(1, 2, 3); // 1
Math.max(...arr); // for an array
Math.pow(2, 10); // 1024
Math.sqrt(16); // 4
Math.cbrt(27); // 3
Math.log(Math.E); // 1
Math.log2(8); // 3
Math.log10(100); // 2
Math.exp(1); // E
Math.sin(angle);
Math.cos(angle);
Math.tan(angle);
Math.asin(value);
Math.atan2(y, x);
Math.random(); // [0, 1)
const r = Math.floor(Math.random() * (max - min + 1)) + min; // integer in [min, max]
Math.hypot(3, 4); // 5
Math.clz32(1); // 31 (count leading zeros)
For cryptographically secure randomness, use crypto.getRandomValues (browser) or crypto.randomBytes (Node.js).
Date
const now = new Date();
const specific = new Date("2026-01-15T10:00:00Z");
const fromMs = new Date(1736937600000);
const fromComponents = new Date(2026, 0, 15, 10, 0, 0); // month is 0-indexed!
now.getFullYear();
now.getMonth(); // 0-11
now.getDate(); // 1-31
now.getDay(); // 0-6 (Sun=0)
now.getHours();
now.getMinutes();
now.getSeconds();
now.getMilliseconds();
now.getTime(); // ms since epoch
now.toISOString();
now.toJSON(); // same as toISOString
now.toLocaleDateString();
now.toLocaleTimeString();
now.toLocaleString("ja-JP");
Date.now(); // current ms
Date.parse("2026-01-15"); // ms
Date.UTC(2026, 0, 15); // ms (UTC components)
The Date is conventional but pitfall-laden (mutable, 0-indexed months, timezone surprises). The substantive alternative is the Temporal API (TC39 Stage 3 as of 2026); @js-temporal/polyfill admits early use. Otherwise, date-fns, dayjs, or Luxon are conventional.
JSON
JSON.stringify(value); // serialise
JSON.stringify(value, null, 2); // pretty-print
JSON.parse(text); // parse
JSON.parse(text, (key, value) => /* reviver */); // with reviver
For custom serialisation, a value’s toJSON method is called by JSON.stringify:
class User {
constructor(public name: string, public age: number, private password: string) {}
toJSON() {
return { name: this.name, age: this.age }; // omit password
}
}
const u = new User("Alice", 30, "secret");
JSON.stringify(u); // {"name":"Alice","age":30}
Promise
Treated in Async and concurrency.
Promise.resolve(value); // already-fulfilled
Promise.reject(error); // already-rejected
Promise.all([p1, p2, p3]); // all fulfil; reject on first error
Promise.allSettled([p1, p2, p3]); // never rejects
Promise.race([p1, p2, p3]); // first to settle
Promise.any([p1, p2, p3]); // first to fulfil
Map, Set, WeakMap, WeakSet
Treated in Data structures.
Error and subclasses
class Error {
name: string;
message: string;
stack?: string;
cause?: unknown; // ES2022
}
// Built-in subclasses:
TypeError // wrong type
RangeError // value out of range
ReferenceError // undeclared variable
SyntaxError // parse error
URIError // bad URI
// AggregateError (ES2021):
new AggregateError([err1, err2], "multiple errors");
Treated in Error handling.
Symbol
The Symbol type admits unique, opaque keys:
const s = Symbol();
const named = Symbol("description");
const id = Symbol.for("global"); // global registry
Symbol.keyFor(id); // "global"
// Well-known symbols (used by the engine):
Symbol.iterator; // for [Symbol.iterator]()
Symbol.asyncIterator;
Symbol.toPrimitive;
Symbol.toStringTag;
class MyClass {
[Symbol.iterator]() { /* ... */ }
}
Symbols are conventional for non-string property keys, particularly for protocol-style methods.
Proxy and Reflect
Proxy admits intercepting object operations:
const handler: ProxyHandler<{ value: number }> = {
get(target, key, receiver) {
console.log(`getting ${String(key)}`);
return Reflect.get(target, key, receiver);
},
set(target, key, value, receiver) {
console.log(`setting ${String(key)} = ${value}`);
return Reflect.set(target, key, value, receiver);
},
};
const p = new Proxy({ value: 0 }, handler);
p.value = 10; // logs "setting value = 10"
console.log(p.value); // logs "getting value", returns 10
Reflect provides functional equivalents to operators:
Reflect.get(obj, "key"); // obj["key"]
Reflect.set(obj, "key", value); // obj["key"] = value
Reflect.has(obj, "key"); // "key" in obj
Reflect.deleteProperty(obj, "key"); // delete obj["key"]
Reflect.ownKeys(obj); // all own keys (incl. symbols)
Reflect.getPrototypeOf(obj);
Reflect.setPrototypeOf(obj, proto);
Reflect.construct(Constructor, args);
Reflect.apply(fn, this, args);
The conventional uses are metaprogramming, validation, ORM-style proxies, and observable state.
Intl
The Intl namespace admits internationalisation:
new Intl.NumberFormat("en-US").format(1234567); // "1,234,567"
new Intl.NumberFormat("ja-JP", { style: "currency", currency: "JPY" }).format(1234567);
new Intl.DateTimeFormat("en-US", {
year: "numeric", month: "long", day: "numeric"
}).format(new Date());
new Intl.RelativeTimeFormat("en", { numeric: "auto" }).format(-1, "day"); // "yesterday"
new Intl.ListFormat("en", { style: "long" }).format(["a", "b", "c"]); // "a, b, and c"
new Intl.Collator("de-DE").compare("ä", "z"); // locale-aware comparison
new Intl.Segmenter("en", { granularity: "word" }).segment("Hello, world!");
crypto
Web Crypto API (browser and modern Node.js):
const buf = new Uint8Array(16);
crypto.getRandomValues(buf);
const id = crypto.randomUUID(); // UUIDv4
// Hashing:
const data = new TextEncoder().encode("hello");
const hash = await crypto.subtle.digest("SHA-256", data);
const hex = Array.from(new Uint8Array(hash))
.map(b => b.toString(16).padStart(2, "0")).join("");
// Encryption (substantive; conventional libraries are layered above):
const key = await crypto.subtle.generateKey(
{ name: "AES-GCM", length: 256 },
true,
["encrypt", "decrypt"],
);
DOM APIs (browser)
The principal browser globals:
document // the document
window // the window
console // logging
document.querySelector(".class");
document.querySelectorAll("p");
document.getElementById("id");
document.createElement("div");
document.body.appendChild(element);
element.classList.add("active");
element.setAttribute("data-id", "123");
element.addEventListener("click", e => /* ... */);
Web APIs
Modern browsers and Node.js (since 18+) admit substantial Web APIs:
// Fetch:
const response = await fetch(url);
const data = await response.json();
// URL:
const u = new URL("https://example.com/path?q=1");
u.searchParams.set("q", "2");
// FormData:
const fd = new FormData();
fd.append("name", "Alice");
fd.append("file", fileBlob);
// Blob:
const blob = new Blob(["hello"], { type: "text/plain" });
// FileReader (browser):
const reader = new FileReader();
reader.onload = () => console.log(reader.result);
reader.readAsText(file);
// AbortController:
const ctrl = new AbortController();
fetch(url, { signal: ctrl.signal });
ctrl.abort();
Node.js APIs
For Node.js targets, common modules:
import { readFile, writeFile, readdir } from "node:fs/promises";
import { join, basename, extname } from "node:path";
import { homedir, platform, cpus } from "node:os";
import { argv, env, exit, cwd } from "node:process";
import { Buffer } from "node:buffer";
import { createServer } from "node:http";
import { connect } from "node:net";
import { spawn, exec } from "node:child_process";
import { Worker } from "node:worker_threads";
import { createHash } from "node:crypto";
The node: prefix admits explicit Node.js built-in imports; conventional in modern code.
The Node.js ecosystem also has a standard library of conventional npm packages:
zod,valibot— schema validation.date-fns,dayjs— date manipulation.undici— HTTP client (faster than fetch in some cases).pino— fast structured logging.
Common patterns
Object transformation
const lowercased = Object.fromEntries(
Object.entries(obj).map(([k, v]) => [k.toLowerCase(), v]),
);
const filtered = Object.fromEntries(
Object.entries(obj).filter(([_, v]) => v !== null),
);
Date arithmetic
const now = new Date();
const tomorrow = new Date(now.getTime() + 24 * 60 * 60 * 1000);
const inAnHour = new Date(now.getTime() + 60 * 60 * 1000);
// Better: use Temporal or date-fns:
import { addDays } from "date-fns";
const tomorrow2 = addDays(now, 1);
Number formatting
const n = 1234567.89;
n.toFixed(2); // "1234567.89"
n.toLocaleString(); // "1,234,567.89" (locale-dependent)
new Intl.NumberFormat("en-US").format(n); // "1,234,567.89"
new Intl.NumberFormat("de-DE").format(n); // "1.234.567,89"
new Intl.NumberFormat("en-US", {
style: "currency", currency: "USD"
}).format(n); // "$1,234,567.89"
Conditional access
const value = obj?.deep?.path?.value ?? defaultValue;
const length = arr?.length ?? 0;
const result = fn?.(arg);
JSON with reviver
const data = JSON.parse(text, (key, value) => {
if (key === "createdAt" && typeof value === "string") {
return new Date(value);
}
return value;
});
Frozen configuration
const config = Object.freeze({
host: "localhost",
port: 8080,
});
// Better, with type-level freeze:
const config = {
host: "localhost",
port: 8080,
} as const;
Hashable map keys via Symbol
const idKey = Symbol("id");
class User {
[idKey]: string;
constructor(id: string) { this[idKey] = id; }
}
Deep clone
const clone = structuredClone(value); // ES2022; deep clone
// Or for JSON-compatible data:
const clone2 = JSON.parse(JSON.stringify(value));
The structuredClone is the conventional contemporary form; admits Date, Map, Set, ArrayBuffer, etc.
Counting via Map
function count<T>(items: T[]): Map<T, number> {
const counts = new Map<T, number>();
for (const item of items) {
counts.set(item, (counts.get(item) ?? 0) + 1);
}
return counts;
}
Async resource management (TS 5.2+)
class Resource implements AsyncDisposable {
async [Symbol.asyncDispose]() { /* cleanup */ }
}
{
await using r = new Resource();
// use r
} // automatic cleanup
TextEncoder/TextDecoder
const encoder = new TextEncoder();
const bytes = encoder.encode("hello"); // Uint8Array
const decoder = new TextDecoder();
const text = decoder.decode(bytes); // "hello"
The mechanism admits substantial conversion between text and bytes; conventional in Web APIs.
A note on the conventional discipline
The contemporary TypeScript standard-library advice:
- Use the JavaScript built-ins — they cover most needs.
- Use
Object.entries/fromEntriesfor typed-object transformations. - Use
Array.fromand theto*non-mutating methods. - Use
Number.isFinite/isInteger/isNaNover the global versions. - Use
Math.randomfor non-cryptographic randomness;crypto.getRandomValuesfor cryptography. - Use
Intl.*for internationalisation. - Use
JSON.stringifywith aspaceargument for pretty-printing. - Use
structuredClonefor deep cloning. - Use
URLfor URL manipulation. - Use
Promise.all/allSettledfor concurrent operations. - Use
crypto.randomUUIDfor unique identifiers. - Use
Temporal/date-fnsover rawDatefor substantial date manipulation. - Use Node.js built-ins via
node:*prefix.
The combination — JavaScript’s built-in objects, the platform-specific APIs (DOM, Node.js), the third-party ecosystem (npm) — is the substance of TypeScript’s runtime library. The discipline lean on the standard built-ins and reach for libraries when substantial functionality is needed; the breadth of the platform admits substantial out-of-the-box capability.