Skip to content

Enhance recursive type #34555

Closed
Closed
@himself65

Description

@himself65

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

Activity

nmain

nmain commented on Oct 18, 2019

@nmain

Possibly related to #33868

HerringtonDarkholme

HerringtonDarkholme commented on Oct 20, 2019

@HerringtonDarkholme
Contributor

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 commented on Oct 30, 2019

@RyanCavanaugh
Member
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Metadata

Metadata

Assignees

No one assigned

    Labels

    DuplicateAn existing issue was already created

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

      Development

      No branches or pull requests

        Participants

        @HerringtonDarkholme@RyanCavanaugh@himself65@nmain

        Issue actions

          Enhance recursive type · Issue #34555 · microsoft/TypeScript