-
Notifications
You must be signed in to change notification settings - Fork 12.5k
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
Covariant assignability of type guard functions is unsound #26981
Comments
We should actually be invariant here, since a contravariant return type would be provably "wrong" since we assume type guards return I like the idea of This would be a breaking change so we'd have to investigate the impact |
@mattmccutchen interested in putting up a PR? We're willing to see how big of a break it would be (expectation is small) |
Fix one break in the compiler, and add a workaround to test case thisPredicateFunctionQuickInfo01, which used a code pattern that no longer works. Fixes microsoft#26981.
PR is #27686. Note the interesting problem with the |
Fix one break in the compiler, and add a workaround to test case thisPredicateFunctionQuickInfo01, which used a code pattern that no longer works. Fixes microsoft#26981.
- Fix one break in the compiler. - Type guards like `isNetworked(): this is (Networked & this)` have been obsolete in favor of `isNetworked(): this is Networked` ever since narrowing was enhanced to take an intersection in a370908, and the first form now causes a problem: a subclass fails to be a subtype of its superclass because `this` appears in a non-covariant position. So replace all occurrences of the first form with the second form in the test suite. Fixes microsoft#26981.
TypeScript Version: master (af8e44a)
Search Terms: user-defined type guard predicate assignable assignability unsound covariant invariant
Code
Expected behavior: Assignability error where marked.
Actual behavior: Successful compilation, runtime error.
Playground Link: link
Related Issues: #24865
If we want a kind of type guard function that is covariant, we need to not narrow when it returns false, i.e., a "true" result would be sufficient but not necessary for the value to be of the tested type. And we'd need a different syntax for the type of a type guard function that is necessary and sufficient compared to a type guard function that is sufficient but not necessary. One idea for the latter is
(x: {}) => x is A | false
. (A type guard function that is necessary but not sufficient would then be(x: {}) => x is A | true
.) Getting all these variants supported would help us support conjunctions and disjunctions of type guard calls with other boolean expressions in #24865. If you like, this issue can be for the removal of the unsound assignability rule and I can file a separate suggestion for the new kinds of type guard functions.The text was updated successfully, but these errors were encountered: