Closed
Description
TypeScript Version: 3.7.0-dev.20191018
Search Terms:
- recursive type
- Recursive type references #33050
Code
Example:
type UnwrapRef<T> = T extends Ref<infer V>
? UnwrapRef<V> // <-- this line will throw error
: T extends Array<infer V>
? Array<UnwrapRef<V>>
: T extends BailTypes
? T // bail out on types that shouldn't be unwrapped
: T extends object ? { [K in keyof T]: UnwrapRef<T[K]> } : T
Expected behavior:
export type UnwrapRef<T> = {
ref: T extends Ref<infer V> ? UnwrapRef<V> : T
array: T extends Array<infer V> ? Array<UnwrapRef<V>> : T
object: { [K in keyof T]: UnwrapRef<T[K]> }
stop: T extends Ref<infer V> ? UnwrapRef<V> : T
}[T extends Ref
? 'ref'
: T extends Array<any>
? 'array'
: T extends BailTypes
? 'stop' // bail out on types that shouldn't be unwrapped
: T extends object
? 'object' : 'stop']
they are the same effects, but why couldn't I code like the first example?
Actual behavior:
Error:(14, 5) TS2315: Type 'UnwrapRef' is not generic.
Playground Link:
https://gist.github.com/Himself65/dea93908f17d25093938fcedc68eabd3
Metadata
Metadata
Assignees
Type
Projects
Milestone
Relationships
Development
No branches or pull requests
Activity
nmain commentedon Oct 18, 2019
Possibly related to #33868
HerringtonDarkholme commentedon Oct 20, 2019
This is expected behavior. Conditional type alone doesn't guarantee recursive type alias. Type alias must have one layer of indirection, e.g., as field of interface, array/tuple's item type, as listed in #33050 .
In this example,
UnwrapRef
directly uses itself in the true branch of conditional type. This fails to meet the "indirection" requirement of recursive type alias.Allowing recursion in conditional type is proposed in #26980 .
Though, I think the error reported here should be "cyclic type alias" rather than "type is not generic".
RyanCavanaugh commentedon Oct 30, 2019
Thanks @nmain / @HerringtonDarkholme ♥