镜像站点 · 本页由第三方 GitHub 只读镜像提供,非 GitHub 官方站点,不接受任何登录或凭据输入。前往 github.com
Skip to content

3.4.0-rc - behaviour changed from 3.3 (regression?) #30489

Description

I found a case where types yielded differ between 3.3 and 3.4, but I'm not sure if it is a regression or it is intended

interface I<T> {
    a: T
}

// this is different between 3.3 and 3.4
type O<T> = T extends I<any> ? T : never
type B = O<I<number>> // I<number> in TS3.3, I<any> & I<number> in TS3.4 (which boils down to I<any>

// this however is the same
type O2<T> = T extends I<infer _> ? T : never
type B2 = O2<I<number>> // I<number> in both

Activity

  1. changed the title [-]3.4 - behaviour changed from 3.3 (regression?)[/-] [+]3.4.0-rc - behaviour changed from 3.3 (regression?)[/+] on Mar 19, 2019
  2. jack-williams commented on Mar 19, 2019

    @jack-williams
    Collaborator

    This is caused by #29437 I think. Not sure I would class this as a regression: is it causing negative behaviour?

  3. xaviergonz commented on Mar 19, 2019

    @xaviergonz
    Author

    At least for me :) , I use it like this

    type ExtendIfI1<T> = T extends I1<any> ? T & Something : T

    I can't use T extends I1<infer X> ? I1<X> & Something : T since if I1 had more stuff than I1 it would be lost, and having to write infer on the left for it to work was hard to find out

    I think it boils down to the generic being inside the template part, this is

    type A<T> = T extends any ? T : never
    type B = A<number> // this is any & number, which is number
    
    type O<T> = T extends I<any> ? T : never
    type B = O<I<number>>
    // could this be changed so it generates I<any & number>, which is I<number>
    // rather than I<any> & I<number> ?
  4. RyanCavanaugh commented on Mar 19, 2019

    @RyanCavanaugh
    Member

    This is the intended behavior to improve inference elsewhere by "collapsing" conditional types into plain types when we detect that's possible.

    One option is to use

    type O<T> = T extends I<unknown> ? T : never

    This will produce the type I<unknown> & I<number> which is indistinguishable from I<number> but also a little ugly.

    You can also make the conditional non-distributive by writing

    type O<T> = [T] extends [I<unknown>] ? T : never
  5. typescript-bot commented on Mar 22, 2019

    @typescript-bot
    Contributor

    This issue has been marked 'Working as Intended' and has seen no recent activity. It has been automatically closed for house-keeping purposes.

  6. weswigham commented on Mar 26, 2019

    @weswigham
    Member

    While the original behavior was intended, its interaction with any is undesirable - to reduce breakage and make better output types, in #30592 we introduce supertype reduction on substitution type instantiation, which should eliminate needless any'd up intersection members in most cases.

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

    Type

    No type

    Projects

    No projects

      Milestone

      No milestone

      Relationships

      None yet

      Development

      No branches or pull requests

      Issue actions