Patterns
How do I make a helper infer a literal tuple without requiring callers to write `as const`?
Mark the type parameter `const`; inference then prefers readonly literal shapes over widened arrays and primitives.
The recipe
function tuple<const T extends readonly unknown[]>(...values: T): T { return values } const statuses = tuple('idle', 'loading', 'done') const point = tuple(10, 20)
The build compiles this and checks each result below.
How it works
- 01
const T extends readonly unknown[]
`const` changes the inference preference; the readonly constraint supplies a compatible narrow target.
- 02
...values: T
The rest parameter records each argument as one tuple position.
What you get
typeof statuses→readonly ["idle", "loading", "done"](typeof statuses)[number]
→"idle" | "loading" | "done"typeof point→readonly [10, 20]
Where it goes wrong
Const inference is shallow and preference-based. Values already stored in widened variables stay widened, and mutable constraints can force the compiler back to mutable arrays.
Takeaway
Use const type parameters at API boundaries where callers benefit from literal precision without extra syntax.
