You signed in with another tab or window. Reload to refresh your session.You signed out in another tab or window. Reload to refresh your session.You switched accounts on another tab or window. Reload to refresh your session.Dismiss alert
{{ message }}
Repository navigation
Truthy check loses effect based on position in "&&" chain #36870
I have three checks in a "&&" chain. The order of the first two checks seems to have an effect on whether I can perform the third check. Am I missing something?
functionf1(x: unknown): any{returnx&&typeofx==='object'&&x.hasOwnProperty('x');// ^ TS reports error: Object is possibly 'null'}functionf2(x: unknown): any{returntypeofx==='object'&&x&&x.hasOwnProperty('x');// no error}
For you to safely call hasOwnProperty on x, x needs to be of type object, and it needs to be non-null.
In f2: After narrowing the type of x using typeof x === 'object', its type is object | null. Narrowing object | null using trueish x && it becomes object.
In f1: However, narrowing unknown with x &&, it is still unknown. Therefor it only has type object | null when you try to call x.hasOwnProperty().
You can see the type by hovering x at the different positions in your playground links.
In the absence of negated types (which themselves have issues) we have no accurate representation of truthy values in the type system. So, an unknown narrowed by a truthiness check is still an unknown. We could potentially consider narrowing to {}, which at least eliminates null and undefined, but {} is an odd type and it doesn't eliminate the other falsy values.
Alternatively, we could special case the pattern of x && typeof x === 'object' and just narrow to object in that case. That's probably the most realistic solution.
Activity
markusjohnsson commentedon Feb 19, 2020
For you to safely call
hasOwnPropertyonx,xneeds to be of typeobject, and it needs to be non-null.In f2: After narrowing the type of
xusingtypeof x === 'object', its type isobject | null. Narrowingobject | nullusing trueishx &&it becomesobject.In f1: However, narrowing
unknownwithx &&, it is stillunknown. Therefor it only has typeobject | nullwhen you try to callx.hasOwnProperty().You can see the type by hovering
xat the different positions in your playground links.ahejlsberg commentedon Mar 16, 2020
In the absence of negated types (which themselves have issues) we have no accurate representation of truthy values in the type system. So, an
unknownnarrowed by a truthiness check is still anunknown. We could potentially consider narrowing to{}, which at least eliminatesnullandundefined, but{}is an odd type and it doesn't eliminate the other falsy values.Alternatively, we could special case the pattern of
x && typeof x === 'object'and just narrow toobjectin that case. That's probably the most realistic solution.