Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Enhance recursive type #34555

Closed
himself65 opened this issue Oct 18, 2019 · 3 comments
Closed

Enhance recursive type #34555

himself65 opened this issue Oct 18, 2019 · 3 comments
Labels
Duplicate An existing issue was already created

Comments

@himself65
Copy link

TypeScript Version: 3.7.0-dev.20191018

Search Terms:

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

@nmain
Copy link

nmain commented Oct 18, 2019

Possibly related to #33868

@HerringtonDarkholme
Copy link
Contributor

HerringtonDarkholme commented 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 RyanCavanaugh added the Duplicate An existing issue was already created label Oct 30, 2019
@RyanCavanaugh
Copy link
Member

Thanks @nmain / @HerringtonDarkholme

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
Duplicate An existing issue was already created
Projects
None yet
Development

No branches or pull requests

4 participants