Open
Description
Bug Report
π Search Terms
Type Guard
π Version & Regression Information
- This changed between versions 4.9.5 and 5.0.4
β― Playground Link
π» Code
declare class Foo<Stuff extends boolean> {
stuff: Stuff extends true ? string : string | undefined;
isReady(): this is Foo<true>
}
declare const x: Foo<boolean>;
if(x.isReady()) {
x
//^? - const x: Foo<boolean>
// Should be Foo<true>
}
π Actual behavior
The Type Guard didn't change the type, which is unintuitive behavior.
π Expected behavior
The method should act as a type guard and change the type
Metadata
Metadata
Assignees
Labels
Type
Projects
Milestone
Relationships
Development
No branches or pull requests
Activity
Andarist commentedon May 8, 2023
Might be related to #53436
graphemecluster commentedon May 25, 2023
The same bug happens in the code snippet from #9619 (comment) and it still presents in the latest nightly build.
Could anyone (perhaps @RyanCavanaugh?) please bisect it?
Andarist commentedon May 25, 2023
@graphemecluster your issue (and this one here) is caused by: #52984 , the one that I linked to here (#53436) was broken before that though
RyanCavanaugh commentedon May 26, 2023
Foo<true>
isn't considered a strict subtype ofFoo<boolean>
due to the variance measurement coming out too conservative when looking atstuff
. TS doesn't have smarts to identify that a conditional type withT
in the true branch andT | U
in the false branch is actually covariant on the tested type parameter - I'm not entirely sure how feasible it would be to do that but it would at least be possible.Counterexample that works:
In this case you can write a variance annotation to make it work as desired:
graphemecluster commentedon May 27, 2023
@RyanCavanaugh Understandable, but #52984 is still a breaking change.