infer Keyword in Conditional Types
debt(d1/e1/b3/t5)
Closest to 'caught instantly (compiler/syntax error)' (d1). The detection_hints note automated: no for general misuse, but the most common mistake — using infer outside a conditional type — is an immediate TypeScript compiler syntax error. The TypeScript compiler (listed in detection_hints.tools) flags this instantly at compile time.
Closest to 'one-line patch or single-call swap' (e1). The quick_fix is a direct pattern substitution: T extends SomeWrapper<infer U> ? U : never. Correcting a misuse or missing branch is a single-line fix within the type declaration itself.
Closest to 'localised tax' (b3). The infer keyword is used within conditional type definitions, which are typically scoped to type utilities or library-level type helpers. While these utilities may be referenced broadly, the infer syntax itself is contained within those type declarations and doesn't impose a broad structural tax on the rest of the codebase.
Closest to 'notable trap (a documented gotcha most devs eventually learn)' (t5). The canonical misconception from the metadata is that infer operates at runtime — it is purely compile-time with no runtime representation. This is a well-documented gotcha that surprises developers coming from value-level programming and is a common but learnable mistake.
TL;DR
Explanation
infer is used in the extends clause of conditional types: type ReturnType<T> = T extends (...args: any[]) => infer R ? R : never. Here infer R captures the return type. Built-in uses: ReturnType<T>, Parameters<T>, InstanceType<T>, Awaited<T>. Custom uses: extracting element type from arrays (T extends (infer U)[] ? U : never), unwrapping Promises, extracting function argument types. infer can only appear on the right-hand side of extends. Multiple infer in one conditional is supported.
Common Misconception
Why It Matters
Common Mistakes
- Using infer outside conditional types — syntax error.
- Not knowing infer captures the narrowest type possible.
- Forgetting the never fallback — conditional types need both branches.
Code Examples
// Without infer — can't extract return type generically:
type GetReturn<T> = any; // No way to extract without infer
// Built-in pattern:
type ReturnType<T> = T extends (...args: any[]) => infer R ? R : never;
// Custom — unwrap array element type:
type ArrayElement<T> = T extends (infer U)[] ? U : never;
type Item = ArrayElement<string[]>; // string
// Custom — unwrap Promise:
type Unwrap<T> = T extends Promise<infer U> ? U : T;