-
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
typeguards only narrow types when used with unary not #44366
Comments
Related: #32819 (comment)
|
That makes sense, and I agree the |
It's always fascinating to read statements like this. To me it's the exact other way around. Having |
I looked into providing negated typeguards, which could be an acceptable workaround if correctly typed, but I have not found a way to represent If looking for these cases is a performance problem, putting it behind a |
I'm much more sympathetic to |
Is this a generally available |
I just ran into a similar (perhaps the same?) issue.
isA() narrows to A (when true) or B (when false). |
@nmain yes, I'm using https://eslint.org/docs/rules/no-restricted-syntax and the relevant selectors are:
|
Another example of lack of code clarity: if (!event.target || event.target instanceof Element === false) throw TypeError('Expected Element');
else if (event.target instanceof HTMLElement === false)) handleElement();
else if (event.target instanceof HTMLAnchorElement) handleAnchor();
else if (event.target instanceof HTMLButtonElement) handleButton();
else if (event.target instanceof HTMLElement) handleHTMLElement(); vs if (!event.target || !(event.target instanceof Element)) throw TypeError('Expected Element');
else if (!(event.target instanceof HTMLElement)) handleElement();
else if (event.target instanceof HTMLAnchorElement) handleAnchor();
else if (event.target instanceof HTMLButtonElement) handleButton();
else if (event.target instanceof HTMLElement) handleHTMLElement(); I think the change would be around here TypeScript/src/compiler/binder.ts Lines 929 to 933 in f84a67f
mimicking how |
This should absolutely be fixed. It does not allow for type guards on |
I just ran across this with #53005. It'd be great to handle this. |
Yay! Will this be in v5.3 or v5.4? |
5.3, #55486 for the schedule. |
Bug Report
🔎 Search Terms
🕗 Version & Regression Information
The FAQ entry with the most promising title is a
TODO
: https://github.com/Microsoft/TypeScript/wiki/FAQ#why-doesnt-isfoox-narrow-x-to-foo-when-isfoo-is-a-type-guardThis occurs on every version of Typescript available in the playground, including nightly.
⏯ Playground Link
Playground Link
💻 Code
🙁 Actual behavior
Comparing the result of a typeguard with
guard(it) === false
or== false
does not narrow the type, but the unary operator with!guard(it)
does narrow it toActor
.🙂 Expected behavior
This may be due to a subtlety with the
entity is Actor
return type not being a proper boolean, but I would expect all forms of negation and comparison tofalse
to narrow the type, and https://www.typescriptlang.org/docs/handbook/2/narrowing.html#equality-narrowing seems to support that. For a typeguard that returns a boolean, the comparisons should be equivalent. Is there some reason that is not the case here?I'm working with lint rules that discourage unary not (easy to miss) and discovered this while doing some refactoring.
The text was updated successfully, but these errors were encountered: