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

Generic type parameter loses defined constraint #51009

Closed
dragomirtitian opened this issue Sep 30, 2022 · 6 comments Β· Fixed by #51076
Closed

Generic type parameter loses defined constraint #51009

dragomirtitian opened this issue Sep 30, 2022 · 6 comments Β· Fixed by #51076
Assignees
Labels
Bug A bug in TypeScript Fix Available A PR has been opened for this issue

Comments

@dragomirtitian
Copy link
Contributor

dragomirtitian commented Sep 30, 2022

Bug Report

πŸ”Ž Search Terms

type parameter constraint

πŸ•— Version & Regression Information

  • This changed between versions 4.9.0-dev.20220914 and 4.9.0-dev.20220915

⏯ Playground Link

Playground link with relevant code

πŸ’» Code

export type TypeA = {
    A: 'A',
    B: 'B',
}
export type TypeB = {
    A: 'A',
    B: 'B',
    C: 'C',
}

// Fails to index TypeA with T
type R<T extends keyof TypeA> =
    T extends keyof TypeB ? [TypeA[T], TypeB[T]] : never

// This one works
type R2<T extends PropertyKey> =
    T extends keyof TypeA ?
    T extends keyof TypeB ?
        [TypeA[T], TypeB[T]] : never: never

πŸ™ Actual behavior

In R, TypeA[T] causes an error: Type 'T' cannot be used to index type 'TypeA'.

πŸ™‚ Expected behavior

TypeA[T] should work since T is by definition constrained to be a keyof TypeA

@RyanCavanaugh
Copy link
Member

@typescript-bot bisect this

@RyanCavanaugh
Copy link
Member

RyanCavanaugh commented Sep 30, 2022

@typescript-bot bisect good v4.8.2 bad main

@typescript-bot typescript-bot added the Has Repro This issue has compiler-backed repros: https://aka.ms/ts-repros label Sep 30, 2022
@typescript-bot
Copy link
Collaborator

The change between v4.8.2 and main occurred at 4110b80.

@RyanCavanaugh RyanCavanaugh changed the title Generic type parameter looses defined constraint Generic type parameter loses defined constraint Sep 30, 2022
@RyanCavanaugh RyanCavanaugh added Needs Investigation This issue needs a team member to investigate its status. and removed Has Repro This issue has compiler-backed repros: https://aka.ms/ts-repros labels Sep 30, 2022
@RyanCavanaugh RyanCavanaugh added this to the TypeScript 4.9.2 milestone Sep 30, 2022
@Andarist
Copy link
Contributor

This regression is specifically caused by including !(constraint.flags & TypeFlags.Never) at this line:
https://github.com/microsoft/TypeScript/pull/50735/files#diff-d9ab6589e714c71e657f601cf30ff51dfc607fc98419bf72e04f6b0fa92cc4b8R19523

In this very case, the source is "C" & T and the target is "A" and the constraint of T is keyof A. This all comes from comparing such source keyof TypeB & T and the target keyof TypeA. The problem is that in this instance the member of the union ("C" & T) is meant to be reduced to never and we want to leverage the fact that never is assignable to just anything. Effectively we want to eliminate this member from the union.

So it seems that the added condition should be only added conditionally - but I don't know what that conditions should be. I've poked around this and tried a couple of things but couldn't make it work.

@ahejlsberg ahejlsberg added Bug A bug in TypeScript and removed Needs Investigation This issue needs a team member to investigate its status. labels Oct 5, 2022
@ahejlsberg
Copy link
Member

ahejlsberg commented Oct 5, 2022

I added the !(constraint.flags & TypeFlags.Never) condition to have intersections that reduce to never appear not comparable to other types such that they're reduced away in CFA. That, in retrospect, isn't correct. I was confused by the fact that we wrongly consider intersections like T & null (where T extends {}) to be unit types, when in reality they're never, and that's actually the issue that needs fixing. I will put up a PR shortly.

@ahejlsberg
Copy link
Member

And, BTW, looks like #51041 is a duplicate of this issue.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
Bug A bug in TypeScript Fix Available A PR has been opened for this issue
Projects
None yet
Development

Successfully merging a pull request may close this issue.

6 participants