-
Notifications
You must be signed in to change notification settings - Fork 13k
Closed
Labels
Design LimitationConstraints of the existing architecture prevent this from being fixedConstraints of the existing architecture prevent this from being fixed
Description
TypeScript Version: 3.5.0-dev.20190514
Search Terms: undefined discriminated union discriminant discriminator unions type guard control flow narrowing
Code
// --strictNullChecks
interface Option1 {
x: true;
}
interface Option2 {
x: false | undefined;
}
type OptionUnion = Option1 | Option2;
function acceptOption1(x: Option1): void {}
function acceptOption2(x: Option2): void {}
function acceptNever(x: never): void {}
function test(anOption: OptionUnion): void {
if (anOption.x === true) {
acceptOption1(anOption);
} else if (anOption.x === false || anOption.x === undefined) {
acceptOption2(anOption);
} else {
acceptNever(anOption);
}
}
Expected behavior:
No errors.
Actual behavior:
acceptNever(anOption);
has an error: Argument of type 'Option2' is not assignable to parameter of type 'never'. ts(2345)
Note that the code works correctly if the discriminator is not a property:
// --strictNullChecks
type Option1 = true;
type Option2 = false | undefined;
type OptionUnion = Option1 | Option2;
function acceptOption1(x: Option1): void {}
function acceptOption2(x: Option2): void {}
function acceptNever(x: never): void {}
function test(anOption: OptionUnion): void {
if (anOption === true) {
acceptOption1(anOption);
} else if (anOption === false || anOption === undefined) {
acceptOption2(anOption);
} else {
acceptNever(anOption); // Not an error - correctly narrows to `never`
}
}
Playground Link:
Related Issues:
#14471 is also using undefined
as a discriminant, although the linked issue is restricting itself to talking about mapped types
Metadata
Metadata
Assignees
Labels
Design LimitationConstraints of the existing architecture prevent this from being fixedConstraints of the existing architecture prevent this from being fixed