Skip to content

Possible regression in conditional types using typescript@4.0.2 #40182

Closed

Description

@traverse

TypeScript Version: 4.0.2

Search Terms: conditional, regression, 4.0.2

Code

type Selector<T> = (selector: T) => any

type Value<T extends Selector<any>> = ReturnType<T> extends string[]
  ? ReturnType<T>[0][]
  : ReturnType<T> extends string
  ? ReturnType<T>[]
  : never

function buildQuery<T = any, S extends Selector<T> = Selector<T>>(selector: S, values: Value<S>) {
  values.forEach(value => {
     // do things with the value
  })
}

Expected behavior:
Using typescript@3.9.5 it used to be the following type (string[] & ReturnType<S>)[0] which can be seen here

Actual behavior:
Using typescript@4.0.2 the type definition changes to an implicit any which can be seen here

Playground Link: See above

Related Issues: I did not find any similar issues.

If any more information is required let me know!

Activity

  1. added
    RescheduledThis issue was previously scheduled to an earlier milestone
    and removed
    RescheduledThis issue was previously scheduled to an earlier milestone
    on Aug 31, 2020
  2. weswigham commented on Oct 22, 2020

    @weswigham
    Member

    This is working as expected now - ReturnType<T> where T is a selector will always resolve to any, and any resolves to both conditional type branches, so you end up with array element types (string[] & ReturnType<S>)[0] and string & ReturnType<S> (realistically, when S is instantiated, these will all collapse to any, but it's not, so it isn't). Practically speaking, we also must consider all branches when looking at constraints while reasoning over generics, any or no. Regardless, these two options mean we have a union of two different array types, meaning values is a union of (array) types, and we're doing .forEach on it. The value parameter type isn't the same across those two overloads, so we type it any (or require a type annotation by issuing an implicit any error with noImplicitAny on).

    Even in 3.9.2, you can actually witness the same behavior if you change Selector to return unknown, rather than any (so it doesn't trigger the buggy behavior with any we previously had).

  3. added
    Working as IntendedThe behavior described is the intended behavior; this is not a bug
    and removed
    Needs InvestigationThis issue needs a team member to investigate its status.
    on Oct 22, 2020
  4. locked as resolved and limited conversation to collaborators on Oct 21, 2025
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Metadata

Metadata

Labels

Working as IntendedThe behavior described is the intended behavior; this is not a bug

Type

No type

Projects

No projects

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions