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
Currently I use a pattern of an in check with a ternary to narrow type on optional fields. With the new optional chaining, it would be great if the type narrowing could occur as the optional chain is progressed.
Use Cases
The primary use here is for type narrowing on union types without the need for extra boilerplate.
Examples
Current method of using the in operator for type narrowing.
Property 'radius' does not exist on type 'Shape'.
Property 'radius' does not exist on type '{ type: "rectangle"; width: number; height: number; }'.(2339)
I would expect it know after the && that shape is a circle.
I think I'm encountering a similar issue when using the new assertion statements:
declarefunctionassertNonNull<T>(x: T|null): asserts x is T;declareconstx: {y: T|null}|null;assertNonNull(x?.y);// Assert y, implicitly assert xdoSomething(x.y);// Error: x is possibly 'null'; the implicit assert for x didn't workassertNonNull(x);// Explicitly assert xdoSomething(x.y);// No error anymore, both x and y have been narrowed down correctly
I've stumbled across what appears to be a similar issue to this one.
Heres a link to the playground. Playground is pointing to nightly but for record keeping I'm seeing this on 3.7.0-dev.20191016
The snippet:
typeFeature={id: string;geometry?: {type: string;coordinates: number[];};};functionextractCoordinates(f: Feature): number[]{if(f.geometry?.type!=='test'){// this case should be hit if f.geometry is undefined return[];}// doesn't narrow f.geometry to the defined valuereturnf.geometry.coordinates;}
We have previously discussed and rejected the notion that
input.headers&&input.headers[key]
should be permitted, since that only establishes that input.headers is truthy, but not what its exact type is (there is no declaration of a headers property in Options which is effectively the same has having a headers of type unknown).
The exact same argument holds for input.headers?.[key] and for that reason we won't implement this suggestion.
You could argue this is also true for the in operator--and you would be right. See discussion in #10485. But this doesn't change the fact that we don't want this behavior for the very common operation of property access using . or ?..
Reacted by Timothy Soehnlin, Ryan Cavanaugh, Lorenzo Bloedow and ljw
Reacted by Marcel Laverdet, Omeid Matten, Patrick Fowler, Saud Ahmed, Tamlyn Rhodes, Tim Shamilov, JD Francis, BenDmg, MentalGear, Kumirei and 7 more
Meanwhile, several comments on this suggestion have pointed out valid issues relating to control flow analysis of optional chaining constructs. We'll track those in #34570.
Activity
itsMapleLeaf commentedon Oct 6, 2019
Maybe this is also related. I ran into an issue with narrowing discriminated unions:
This errors on
radiusinshape?.radius:I would expect it know after the
&&thatshapeis a circle.Playground
Kingwl commentedon Oct 7, 2019
@kingdaro @zhongliangwang
Seems fixed in #33821
itsMapleLeaf commentedon Oct 9, 2019
Found another similar problem: narrowing doesn't happen properly with
switchPlayground
In the latest nightly as of this comment, this does typecheck if I refactor this to if statements
HoldYourWaffle commentedon Oct 9, 2019
I think I'm encountering a similar issue when using the new assertion statements:
I'm using the latest nightly as of 9 october.
ryanquinn3 commentedon Oct 16, 2019
I've stumbled across what appears to be a similar issue to this one.
Heres a link to the playground. Playground is pointing to nightly but for record keeping I'm seeing this on
3.7.0-dev.20191016The snippet:
Kingwl commentedon Oct 17, 2019
Ryan Quinn (@ryanquinn3)
That seems expected behavior
ahejlsberg commentedon Oct 18, 2019
We have previously discussed and rejected the notion that
should be permitted, since that only establishes that
input.headersis truthy, but not what its exact type is (there is no declaration of aheadersproperty inOptionswhich is effectively the same has having aheadersof typeunknown).The exact same argument holds for
input.headers?.[key]and for that reason we won't implement this suggestion.You could argue this is also true for the
inoperator--and you would be right. See discussion in #10485. But this doesn't change the fact that we don't want this behavior for the very common operation of property access using.or?..ahejlsberg commentedon Oct 18, 2019
Meanwhile, several comments on this suggestion have pointed out valid issues relating to control flow analysis of optional chaining constructs. We'll track those in #34570.