🔎 Search Terms
narrowing, strict equals, property access, boolean false, undefined
🕗 Version & Regression Information
- This changed between versions 5.2 and 5.3
- This also happens in the nightly
⏯ Playground Link
https://www.typescriptlang.org/play?ts=5.3.1-rc#code/JYOwLgpgTgZghgYwgAgGIHt3IN4ChnIBGcUAXEZgDYRwi4C+uuC6IAzmMgOYRgZYBeZAAoAlOX7IAPsgCuIACYQYoCAuQCAfDnzIovWVBDIAsnDAALAHRRaC9AFsxybQAYrAVmQB+HERLk8JRsKPTI5PJKKiBqDEws7JwwmBrcvPxiuMAwIsno3lbEUBoCQkEhojoECWzo1FaU6FzCeaJxuAD0HcgAAmBsALQQAB4ADhAIYENQUOjFA8h5yMBsyKPobGzAhJQAnnKKyqoKzKy19Y3NeYUkbUA
💻 Code
interface Foo {
bar: boolean
}
const getFoo = (): Foo | undefined => {
return Math.random() > 0.5 ? { bar: false } : undefined
}
const foo = getFoo()
if (foo?.bar === false) {
console.log(foo)
}
// @ts-expect-error - foo is possibly undefined
console.log(foo.bar)
🙁 Actual behavior
In line 13 and following, foo is incorrectly narrowed to just Foo (whereas it was previously Foo | undefined), although we learned nothing about it from the preceding if as that did not influence control flow.
Unused '@ts-expect-error' directive.(2578)
🙂 Expected behavior
TS should report an error when accessing foo.bar as foo can potentially be undefined.
Additional information about the issue
I originally discovered this issue in JSX with a snippet similar to:
function Component () {
const foo = getFoo()
return (
<div>
{foo?.bar === false && 'foo'}
{foo.bar ? 'true' : 'false'}
</div>
)
}
There as well, the access foo.bar is allowed due to the preceding check, although they are completely separate.
Note that changing it to === true or removing the checks entirely fixes the problem.
🔎 Search Terms
narrowing, strict equals, property access, boolean false, undefined
🕗 Version & Regression Information
⏯ Playground Link
https://www.typescriptlang.org/play?ts=5.3.1-rc#code/JYOwLgpgTgZghgYwgAgGIHt3IN4ChnIBGcUAXEZgDYRwi4C+uuC6IAzmMgOYRgZYBeZAAoAlOX7IAPsgCuIACYQYoCAuQCAfDnzIovWVBDIAsnDAALAHRRaC9AFsxybQAYrAVmQB+HERLk8JRsKPTI5PJKKiBqDEws7JwwmBrcvPxiuMAwIsno3lbEUBoCQkEhojoECWzo1FaU6FzCeaJxuAD0HcgAAmBsALQQAB4ADhAIYENQUOjFA8h5yMBsyKPobGzAhJQAnnKKyqoKzKy19Y3NeYUkbUA
💻 Code
🙁 Actual behavior
In line 13 and following,
foois incorrectly narrowed to justFoo(whereas it was previouslyFoo | undefined), although we learned nothing about it from the precedingifas that did not influence control flow.🙂 Expected behavior
TS should report an error when accessing
foo.barasfoocan potentially be undefined.Additional information about the issue
I originally discovered this issue in JSX with a snippet similar to:
There as well, the access
foo.baris allowed due to the preceding check, although they are completely separate.Note that changing it to
=== trueor removing the checks entirely fixes the problem.