How to fix Conditional type cannot reference type variable in constraint in TypeScript
This error occurs when you try to reference a type variable inside the constraint portion of a conditional type. TypeScript doesn't allow using inferred type variables or parameters in the extends clause because constraints are evaluated before inference happens. The fix involves restructuring your type to reference the variable in the branches instead of the constraint.
Quick fix
Fixes Conditional type cannot reference type variable in constraint
type Wrong<T> = T extends (infer U extends string)[] ? U : never;
// Error: Cannot reference inferred type in constraint- Understand constraint versus branch scope
- Move constraints to the outer type parameter
- Use nested conditional types instead of complex constraints
- Restructure to infer first, then apply constraints in branches
type Wrong<T> = T extends (infer U extends string)[] ? U : never;// Error: Cannot reference inferred type in constraintConditional type cannot reference type variable in constraint
What this error means
Conditional types in TypeScript use the syntax `T extends Condition ? TrueType : FalseType` to select different types based on patterns. The error 'Conditional type cannot reference type variable in constraint' occurs when you attempt to reference a type variable (typically one being inferred) inside the extends clause itself. This happens because: - The constraint portion of a conditional type is evaluated before the type body - Type variables captured with `infer` can only be used in the branches, not in constraints - Constraints define what types are allowed, while branches use those inferred types - TypeScript's type resolution order doesn't permit referencing inferred variables in their own constraint
Typical symptoms
- TypeScript compiler error: 'Conditional type cannot reference type variable in constraint'
- Error appears when using infer inside an extends clause
- The error points to a line attempting to use inferred types in the condition
- Generic types with constraints that try to reference inferred types fail
- Deeply nested conditional types trigger the error unexpectedly
Common causes
- Using inferred type variables (with infer keyword) in the extends clause instead of branches
- Attempting to constrain a conditional type based on an inferred variable
- Complex type manipulation that tries to both infer and constrain simultaneously
- Misunderstanding the evaluation order of conditional type constraints versus branches
- Trying to use a type parameter in a constraint when it's only available after inference
How to fix "Conditional type cannot reference type variable in constraint"
The constraint portion of a conditional type (after extends) is evaluated first and cannot reference inferred types. Only the true and false branches can use inferred variables.
Wrong - constraint tries to reference inferred type:
type Wrong<T> = T extends (infer U extends string)[] ? U : never;
// Error: Cannot reference inferred type in constraintCorrect - reference inferred type in branch:
type Correct<T> = T extends (infer U)[] ? (U extends string ? U : never) : never;The key difference: the constraint checks if T is an array, then the branch checks if U (the inferred element type) is a string.
If you need to constrain a type variable, apply the constraint to the generic type parameter itself, not in the conditional clause.
Problem:
type ExtractString<T> = T extends (infer Item extends string)[] ? Item : never;
// Error: Cannot reference inferred type in constraintSolution - constrain the outer parameter:
type ExtractString<T extends string[]> = T extends (infer Item)[] ? Item : never;Or use the constraint in TypeScript 5+ style:
type ExtractString<T> = T extends (infer Item)[]
? (Item extends string ? Item : never)
: never;When you need to both infer and constrain a type, use nested conditionals where the inner conditional checks the constraint.
Problem:
type GetProperty<T, K> = T extends Record<K extends string ? K : never, infer V> ? V : never;
// Error: Cannot use constraint with inferred typeSolution - nested conditionals:
type GetProperty<T, K> = K extends string
? K extends keyof T
? T[K]
: never
: never;This first checks if K is a string, then checks if it's a key of T, avoiding the constraint reference problem.
Refactor your conditional type to infer the variable first at the top level, then apply constraints in the branches.
Problem:
type Unwrap<T> = T extends Promise<infer U extends { id: string }> ? U : T;
// Error: Cannot reference inferred type in constraintSolution - separate inference from constraint:
type Unwrap<T> = T extends Promise<infer U>
? (U extends { id: string } ? U : never)
: T;The key is: infer U without constraints, then check the constraint in the branch.
TypeScript 5.4 introduced support for constraints on inferred types, but with specific syntax. Ensure you're using the correct syntax for your version.
TypeScript 5.4+ correct syntax:
// This syntax IS allowed in 5.4+ when properly structured
type GetString<T> = T extends (...args: any[]) => (infer R extends string)
? R
: never;However, this only works in specific contexts (like function return types). For array element inference, use the nested approach:
type GetStringElement<T> = T extends (infer E)[]
? E extends string ? E : never
: never;Check your tsconfig.json for the compilerOptions.target or compilerOptions.lib to ensure you're on TypeScript 5.4+.
If your conditional type is complex, create intermediate helper types to handle inference and constraints separately.
Problem:
type Complex<T> = T extends {
data: (infer Items extends { id: string })[]
} ? Items : never;
// Error: Cannot reference inferred type in constraintSolution - split into helper types:
// First helper: extract the array
type ExtractDataArray<T> = T extends { data: infer D } ? D : never;
// Second helper: extract array elements
type ArrayElements<T> = T extends (infer E)[] ? E : never;
// Third helper: check if has id
type HasId<T> = T extends { id: string } ? T : never;
// Compose them
type Complex<T> = HasId<ArrayElements<ExtractDataArray<T>>>;This approach is clearer and avoids the constraint reference error.
Advanced notes
### Why This Limitation Exists
TypeScript evaluates conditional types in this order:
1. Constraint evaluation: Check if T extends the constraint
2. Inference: If matched, capture inferred types using infer
3. Branch selection: Choose true or false branch based on match
4. Branch evaluation: Evaluate the selected branch with inferred types
Since constraints are evaluated in step 1 before inference happens in step 2, inferred variables don't exist yet when constraints are being checked. This is a fundamental limitation of TypeScript's type evaluation model.
### Type Inference Precedence
When TypeScript sees a conditional type, it follows this precedence:
1. Type parameters must be fully defined or inferrable from context
2. Constraints apply to type parameters (not inferred types)
3. Inferred types are captured during constraint matching
4. Branches can use both original parameters and inferred types
### Working Patterns
Extracting from a discriminated union:
type UnionToIntersection<U> = (U extends any ? (k: U) => void : never) extends (k: infer I) => void ? I : never;Extracting function parameters:
type Parameters<T extends (...args: any) => any> = T extends (...args: infer P) => any ? P : never;Extracting Promise type:
type Awaited<T> = T extends Promise<infer U> ? U : T;All these work because the constraint is on the outer parameter T, not on the inferred type.
### Related Errors
- "Type 'U' does not satisfy the constraint": Check if U is constrained in the correct scope
- "Inferred type cannot reference itself": Avoid recursive references in inferred types
- "Type parameter is not known to satisfy constraint": Ensure the parameter type matches the constraint
Frequently asked questions
- What does "Conditional type cannot reference type variable in constraint" mean?
- Conditional types in TypeScript use the syntax T extends Condition ? TrueType : FalseType to select different types based on patterns. The error 'Conditional type cannot reference type variable in constraint' occurs when you attempt to reference a type variable (typically one being inferred) inside the extends clause itself.
- How do I fix "Conditional type cannot reference type variable in constraint"?
- This error occurs when you try to reference a type variable inside the constraint portion of a conditional type. TypeScript doesn't allow using inferred type variables or parameters in the extends clause because constraints are evaluated before inference happens. The fix involves restructuring your type to reference the variable in the branches instead of the constraint.
- What causes "Conditional type cannot reference type variable in constraint"?
- Using inferred type variables (with infer keyword) in the extends clause instead of branches Attempting to constrain a conditional type based on an inferred variable Complex type manipulation that tries to both infer and constrain simultaneously
- Is the "Conditional type cannot reference type variable in constraint" error serious?
- It is a medium-severity error โ more of a blocker than a risk. The steps above resolve it.
Official resources & further reading
- ๐TypeScript Official Documentation
- ๐TypeScript Handbook - Conditional Types(Official Docs)
- ๐TypeScript Handbook - Inferring Within Conditional Types(Official Docs)
- ๐TypeScript 5.4 Release Notes - Inferred Type Constraints(Official Docs)
- ๐
- ๐