-
Notifications
You must be signed in to change notification settings - Fork 12.8k
Optional Chaining and Type Narrowing #33736
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
Thumb up to this issue. Type narrowing is not working with declare const foo: { bar: string, method: () => void } | undefined;
if (foo?.bar === 'SUCCESS') {
foo.method();
} |
Maybe this is also related. I ran into an issue with narrowing discriminated unions: type Shape =
| { type: 'rectangle', width: number, height: number }
| { type: 'circle', radius: number }
declare const shape: Shape | undefined
const radius = shape?.type === 'circle' && shape?.radius This errors on
I would expect it know after the |
@kingdaro @zhongliangwang |
Found another similar problem: narrowing doesn't happen properly with type Shape =
| { type: 'rectangle', width: number, height: number }
| { type: 'circle', radius: number }
function getArea(shape?: Shape) {
switch (shape?.type) {
case 'circle':
return Math.PI * shape.radius ** 2
case 'rectangle':
return shape.width * shape.height
default:
return 0
}
} In the latest nightly as of this comment, this does typecheck if I refactor this to if statements |
I think I'm encountering a similar issue when using the new assertion statements: declare function assertNonNull<T>(x: T | null): asserts x is T;
declare const x: { y: T | null } | null;
assertNonNull(x?.y); // Assert y, implicitly assert x
doSomething(x.y); // Error: x is possibly 'null'; the implicit assert for x didn't work
assertNonNull(x); // Explicitly assert x
doSomething(x.y); // No error anymore, both x and y have been narrowed down correctly I'm using the latest nightly as of 9 october. |
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 The snippet: type Feature = {
id: string;
geometry?: {
type: string;
coordinates: number[];
};
};
function extractCoordinates(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 value
return f.geometry.coordinates;
} |
That seems expected behavior |
We have previously discussed and rejected the notion that input.headers && input.headers[key] should be permitted, since that only establishes that The exact same argument holds for You could argue this is also true for the |
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. |
Search Terms
Optional Chaining
Suggestion
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.Improved syntax given optional chaining
Checklist
My suggestion meets these guidelines:
The text was updated successfully, but these errors were encountered: