const Type Parameters (TS 5.0)
debt(d7/e1/b1/t5)
Closest to 'only careful code review or runtime testing' (d7). The detection_hints indicate automated detection is 'no' and the only tool is the TypeScript compiler itself — but the compiler won't flag misuse (e.g. using const type params when widened types are needed). A developer must notice through code review that literal inference is undesired or that readonly was omitted; there's no linter rule or SAST catching these misuses automatically.
Closest to 'one-line patch or single-call swap' (e1). The quick_fix confirms it's simply adding or removing the const modifier on a type parameter declaration — a trivial one-character/one-word change at the function signature level.
Closest to 'minimal commitment' (b1). This is a type-level modifier on individual generic function signatures. It imposes no structural obligation on callers or the rest of the codebase — each usage is self-contained, and removing or adding it is a one-line change with no cross-cutting consequences.
Closest to 'notable trap' (t5). The misconception field explicitly calls out that developers familiar with Rust confuse this with Rust's const generics (value-level computation), when TypeScript's version is purely about literal type inference. Additionally, common mistakes include confusing it with the const keyword and forgetting readonly for tuple preservation — documented gotchas that competent developers encounter and must learn.
TL;DR
Explanation
Without const, TypeScript widens inferred types: function identity<T>(x: T): T with identity(['a','b']) infers T as string[]. With const modifier: function identity<const T>(x: T): T infers T as readonly ['a', 'b']. This enables more precise inference without requiring 'as const' at the call site. Use cases: route definitions, action creators, tuple preservation. The const modifier on a type parameter is similar to inferring with as const. Works with object types too — properties become readonly with literal types.
Common Misconception
Why It Matters
Common Mistakes
- Using const type params when widened types are actually needed.
- Not combining with readonly for tuple preservation.
- Confusing with the const keyword — this is a type-level modifier.
Code Examples
function makeRoute<T extends string>(path: T) { return path; }
const r = makeRoute('/users'); // T inferred as string, not '/users'
function makeRoute<const T extends string>(path: T) { return path; }
const r = makeRoute('/users'); // T inferred as '/users' literal
// With arrays:
function tuple<const T extends unknown[]>(...args: T): T { return args; }
const t = tuple(1, 'two', true); // [1, 'two', true] not (number|string|boolean)[]