← Home ← Codex ← DEBT
Browse by Category
+ added · updated 7d
← Back to glossary

Conditional Types & infer

TypeScript 2.8 Advanced
debt(d5/e3/b3/t7)
d5 Detectability Operational debt — how invisible misuse is to your safety net

Closest to 'specialist tool catches it' (d5). The detection_hints list TypeScript's own type checker and ESLint as tools. Misuse of conditional types (e.g., wrong distributivity assumptions, infinite recursion, using 'any' where conditional types would narrow correctly) is caught by the TypeScript compiler — a specialist type-checking tool — not by a standard linter alone. Syntax errors are caught instantly, but semantic misuse (e.g., distributivity surprises producing 'boolean' instead of 'true') surfaces only under TypeScript's type analysis, placing it squarely at d5.

e3 Effort Remediation debt — work required to fix once spotted

Closest to 'simple parameterised fix' (e3). The quick_fix describes replacing patterns with 'T extends U ? X : Y' or adding 'infer' keyword, which is a targeted refactor within one component or type definition. Common mistakes like forgetting infer or mishandling distributivity typically require editing a type definition and its usages in one area — more than a one-liner but not cross-cutting. This fits e3.

b3 Burden Structural debt — long-term weight of choosing wrong

Closest to 'localised tax' (b3). Conditional types apply to web and cli contexts but are confined to type-level code in TypeScript. A poorly written conditional type imposes a tax on maintainers who need to understand it, but the impact is localised to the type definitions and the functions/components using them. The rest of the codebase is largely unaffected unless the type is deeply shared.

t7 Trap Cognitive debt — how counter-intuitive correct behaviour is

Closest to 'serious trap' (t7). The misconception field notes that developers think conditional types are impractical, but the deeper trap captured in common_mistakes is distributivity: 'T extends string ? true : false' where T = string | number gives 'boolean' not 'true'. This contradicts how developers expect type-level conditionals to behave (analogous to value-level ternaries), and it contradicts the non-distributive behaviour of overloads in other systems. Infinite recursion is a secondary serious trap. Together these score t7.

About DEBT scoring →

Also Known As

conditional types infer keyword TypeScript type inference

TL;DR

Types that choose between two types based on a condition — T extends U ? X : Y — enabling type-level branching. The infer keyword extracts types from within a conditional.

Explanation

Conditional types: T extends Condition ? TrueType : FalseType. Distributive conditional types: when T is a union, the condition distributes over each member. The infer keyword captures a type variable within the extends clause: T extends Promise<infer U> ? U : never extracts the resolved type of a Promise. Built-in TypeScript utilities using conditional types: ReturnType<T>, Parameters<T>, InstanceType<T>, Awaited<T>. Essential for building type utilities that work with generic type shapes.

Common Misconception

Conditional types are too complex to be practical — ReturnType<T>, Parameters<T>, and Awaited<T> are all conditional types used daily; they are essential for framework types and generic utilities.

Why It Matters

Without conditional types, you cannot express that a function returns the resolved type of a promise, or that a generic utility behaves differently for arrays vs non-arrays — conditional types unlock these patterns.

Common Mistakes

  • Forgetting distributivity — T extends string ? true : false where T = string | number gives boolean, not true.
  • Infinite type recursion — conditional types can recurse; TypeScript limits depth.
  • Using conditional types where generics or overloads are cleaner.
  • Not using infer when extracting nested types — manual type indexing is error-prone.

Code Examples

✗ Vulnerable
// Manual return type extraction — not generic:
type StringFuncReturn = string;
type NumberFuncReturn = number;
// Need separate type for every function signature
✓ Fixed
// Conditional type with infer — works for any function:
type ReturnType<T extends (...args: any) => any> =
    T extends (...args: any) => infer R ? R : never;

// Unwrap Promise:
type Awaited<T> = T extends Promise<infer U> ? Awaited<U> : T;

// Extract array element type:
type ElementType<T> = T extends (infer U)[] ? U : never;

type A = ElementType<string[]>;  // string
type B = Awaited<Promise<number>>; // number

// Distributive:
type NonNullable<T> = T extends null | undefined ? never : T;
type C = NonNullable<string | null | undefined>; // string

Added 16 Mar 2026
Edited 22 Mar 2026
Views 61
Rate this term
No ratings yet
🤖 AI Guestbook educational data only
| |
Last 30 days
0 pings T 1 ping W 2 pings T 0 pings F 0 pings S 0 pings S 0 pings M 0 pings T 1 ping W 2 pings T 2 pings F 2 pings S 4 pings S 3 pings M 1 ping T 0 pings W 0 pings T 0 pings F 0 pings S 0 pings S 0 pings M 1 ping T 0 pings W 0 pings T 0 pings F 0 pings S 0 pings S 0 pings M 2 pings T 0 pings W
No pings yet today
PetalBot 2
Scrapy 11 Amazonbot 10 Perplexity 9 Ahrefs 4 SEMrush 4 Google 2 Unknown AI 2 Bing 2 PetalBot 2 Claude 1 ChatGPT 1 Meta AI 1
crawler 47 crawler_json 1 pre-tracking 1
DEV INTEL Tools & Severity
🟢 Low ⚙ Fix effort: High
⚡ Quick Fix
Use conditional types T extends U ? X : Y for type-level if statements — infer keyword within conditional types lets you extract type information from complex generics
📦 Applies To
typescript 2.8 web cli
🔗 Prerequisites
🔍 Detection Hints
Function overloads that could be replaced by a single generic signature with conditional return type; type any used where conditional type would narrow correctly
Auto-detectable: ✓ Yes typescript eslint
⚠ Related Problems
🤖 AI Agent
Confidence: Low False Positives: High ✗ Manual fix Fix: High Context: File


✓ schema.org compliant