-
Notifications
You must be signed in to change notification settings - Fork 12.8k
Inconsistency with boolean negation as void
type guards with --strictNullChecks
#33180
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
Comments
Alleged bug aside, It's very suspicious when you accept
It's also possible for a "void" function to actually return 999 or "hello, world", or some other value |
Sure, that was just a contrived example, though. A more realistic situation would be when handling some promise that has a // foo's type is Promise<string | void>
const foo = new Promise<string>(res => res('foo')).catch((err: any) =>
console.log('I don't know what option types are')
); You await a function that returns a value like this, and now you have to deal with a I think this is irrelevant to the current question, though. The fact that the function in my example accepts |
I would personally expect all 3 examples to error, no matter what. Because It really means "I may or may not have a value but don't try to use me!" So, you could have a variable of type string|void... But it has a number value! The only thing I would expect is that, to narrow string|void to string, you have to use |
Yes, that would also be much more consistent to me. The issue body is a bit long, so to summarize:
I do not think Edit: Accidentally hit 'comment and close,' please ignore. |
Yeah, to clarify on what @AnyhowStep said from a more solid theoretical basis: function foo(): string { return "foo"; }
let bar: () => void = foo;
let result: void | string = bar(); Here, if you're only allowed to see the type of |
Thanks, that does clarify things. Would you recommend I edit the original issue to focus more on the fact that |
The fact that It's generally safe to assume that Now the above having been said, (async () => {
async function foo(): Promise<string> { return "foo"; }
let bar: () => Promise<void> = foo; // <-- type error here
let result: void | string = await bar();
})(); I'm not yet convinced that's enough to guarantee |
Likely a duplicate of #32809; the first two functions are leaking false information about |
Oh good, @RyanCavanaugh agrees with me that the current typeguard behavior is wrong. 😃 |
Yep, seems like a duplicate of #32809. |
TypeScript Version:
[email protected]
Search Terms: void guard strictNullChecks boolean negation refinement
Code
Expected behavior:
strictNullChecks: false
behaves less strictly thanstrictNullChecks: true
. Admittedly a loose criterion, but it seems like the stricter check fails withstrictNullChecks: false
and passes withstrictNullChecks: true
, while the type coercive check passes in both cases.My confusion stems from the fact that
!
is a valid type guard forvoid
for both compiler flags, while checking againstnull
andundefined
is valid forstrictNullChecks: true
only.As a bonus, while
!
is always valid,!Boolean(x)
is never valid.Actual behavior:
getMaybeStringLen
...strictNullChecks: true
strictNullChecks: false
getMaybeStringLenBoolNegation
...strictNullChecks: true
strictNullChecks: false
getMaybeStringLenBoolCoercionNegation
...strictNullChecks: true
strictNullChecks: false
Playground Link: http://www.typescriptlang.org/play/#code/PTAEBUHsHNoGwKagM4BcBOBLAxqgcgK5xwDCAFgtgNbKiQBm9oAhgHYAmKCSqFoqATwAOSBOnSR0LISOboAUCDqtQcTKyQB2ADSgA7mUyJQAJg6h6KjQDcxoMRPS02nAMzpOzOHuYDaDyWR5bEhWNFBoBFQAWV8AIwQAZQx1aAAZBBUAXlAACgBbeKSU1mgALhQS6FAAH1BrSEx2AEpQLIA+UABveVBQTCYCouSsUrasnNYiOFq6woEEkdTxnIIOBHp1BBbu3r7QdCiCdBU19g2t9gBuPYBfPcPUY5V5xaqAOkRS3hvbm+DQuFIjFhlUMqwAEKQSBwPAIaDMVCYUJtPKvYqjcqVTG1eqNHYdXZ9AZ5ACE6KWpVaPX2ByOJ1AZwuGmudwe9JeoMxn0y0B+8j+8gBYVQESisQWGNS4KhMJIkDE2GRrDhCKRKJyQ0llKxaBxdQaTVahJp-UGpNliDYWremOa1L2fUez0Z602LJufXuTo5oApHy+fLIvxuQA
Related Issues: #1806, #8322, #10564
The text was updated successfully, but these errors were encountered: