The 'const' modifier on a type parameter (TS 5.0+) tells the inference engine to treat the argument as if the caller had written 'as const' — preserving string literals, readonly arrays, and tuple shapes. This eliminates the need to manually annotate every nested literal and unlocks design patterns like type-safe routing tables, state machine definitions, and configuration DSLs where the precise literal values feed downstream conditional types. The caller writes a plain object; the library captures it at maximum precision. Combine with 'satisfies' at the call site when you also want to constrain the structural shape without losing literal narrowing.
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"