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

Checked type of conditional type isn't matched for constraint in true clause unless the type parameter is constrained #31700

Closed
sirian opened this issue May 31, 2019 · 4 comments
Assignees
Labels
Working as Intended The behavior described is the intended behavior; this is not a bug

Comments

@sirian
Copy link
Contributor

sirian commented May 31, 2019

TypeScript Version: 3.5.1

Code

type Ctor = new () => Date;

 // ERROR, WTF?
type Z1<T> = T extends () => Ctor ? InstanceType<ReturnType<T>> : never; 

// But here NO ERROR
type Z2<T extends any> = T extends () => Ctor ? InstanceType<ReturnType<T>> : never;


 // ERROR
type Z3<T> = T extends () => any ? InstanceType<ReturnType<T>> : never;

// NO ERROR again
type Z4<T extends () => any> = InstanceType<ReturnType<T>>;

Actual behaviour
type Z1<T> = T extends () => Ctor ? InstanceType<ReturnType<T>> : never; errors

Expected behaviour
type Z1<T> = T extends () => Ctor ? InstanceType<ReturnType<T>> : never; should be valid

More examples.
image

Playground Link:

@RyanCavanaugh RyanCavanaugh added the Bug A bug in TypeScript label May 31, 2019
@RyanCavanaugh RyanCavanaugh added this to the TypeScript 3.6.0 milestone May 31, 2019
@RyanCavanaugh
Copy link
Member

Regressed between 3.3 and 3.4

@RyanCavanaugh RyanCavanaugh changed the title Type infer broken in 3.5 Checked type of conditional type isn't matched for constraint in true clause unless the type parameter is constrained May 31, 2019
@weswigham
Copy link
Member

Technically this is because we erase any in a substitution (or rather, we interpret it as unknown so as to not delete information). So a T extends any ? InstanceType<ReturnType<T>> : never is essentially InstanceType<ReturnType<T & unknown>> which is just InstanceType<ReturnType<T>> which is ofc an error. The others all formulate in the same way. Essentially, any as a conditional check does not disable type checking, like any as a constraint (accidentally!) does. #29571 would go a lot of the way to making the constraint cases behave like the conditionals (though it's still admittedly incomplete! it only replaces any at the top level of a constraint and not throughout the constraint type!)

So this is technically a regression, but it's an intended consequence of an intentional change, and what we have been looking at is making the constraint case behave in the same way, too (as why would a T extends any be any different than a T extends unknown???)

@weswigham weswigham added Working as Intended The behavior described is the intended behavior; this is not a bug and removed Bug A bug in TypeScript labels Jul 25, 2019
@weswigham
Copy link
Member

@RyanCavanaugh if you want, we can discuss this, but after actually looking at it, everything seems in order except for our constraint behavior which we already acknowledge as wrong.

@typescript-bot
Copy link
Collaborator

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

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
Working as Intended The behavior described is the intended behavior; this is not a bug
Projects
None yet
Development

No branches or pull requests

5 participants