typescript / expert
Snippet
Literal-Erhaltung durch const-Typparameter
Der 'const'-Modifier auf einem Typparameter (TS 5.0+) weist die Inferenz an, das Argument so zu behandeln, als hätte der Aufrufer 'as const' geschrieben — String-Literale, readonly Arrays und Tuple-Formen bleiben erhalten. Das erspart manuelle Annotationen jedes verschachtelten Literals und ermöglicht Patterns wie typsichere Routing-Tabellen, State-Machine-Definitionen oder Config-DSLs, in denen die exakten Literale nachgelagerte Conditional Types speisen. Der Aufrufer schreibt ein einfaches Objekt; die Bibliothek erfasst es mit maximaler Präzision. Kombiniere es bei Bedarf mit 'satisfies' am Call-Site, um die Struktur zusätzlich zu beschränken.
snippet.ts
typescript
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
function defineRoutes<const T extends Record<string, { path: string; method: "GET" | "POST" }>,>(routes: T): T {return routes;}const api = defineRoutes({users: { path: "/users", method: "GET" },create: { path: "/users", method: "POST" },});// Without 'const T', method would widen to the union "GET" | "POST".// With 'const T', each literal is preserved exactly:type UsersMethod = typeof api.users.method; // "GET"type CreateMethod = typeof api.create.method; // "POST"type RouteNames = keyof typeof api; // "users" | "create"
Erklärung
1
function defineRoutes<const T extends Record<string, ...>>(routes: T): T
'const T' lässt die Inferenz das Argument als tief readonly mit erhaltenen Literalen behandeln.
2
users: { path: "/users", method: "GET" },
Schlichtes Objekt-Literal — kein 'as const'-Suffix am Call-Site nötig.
3
type UsersMethod = typeof api.users.method;
Wird zu "GET" aufgelöst, nicht "GET" | "POST" — jede Property behält ihr exaktes Literal.
4
type RouteNames = keyof typeof api;
Ergibt die Union der literalen Keys und erlaubt nachgelagert typsichere Lookups per Name.