π Search Terms
narrowing, discriminated, union, member, count
π Version & Regression Information
Tested on 3.3.3333, 5.9.3, 6.0.2, and 7.0.2, all exhibit the problem.
β― Playground Link
https://www.typescriptlang.org/play/?allowUnreachableCode=true#code/CYUwxgNghgTiAEYD2A7AzgF3gMyUgjAFzwDe8GxADANzwAexKArgLYBGIMtAno6x13gBfagCg0AdwCWGMAAt4AClwEAdBgCUpUfF2IoaBJWIY5MJBPgAiK2KGjk6LAH0pLAA5I0aKWwggieBQQADdOeABeHDx8WgB6OPgmFAMfAHMUvxBRHNBIWARHTGikACZiMgp4Gno+dk4eOoFaIXgAH1JyYlj4AC9iTBgpFDSWsUkZeSUVUvUtEh09MAMjEzMLa1tF3WXDeEDTc0sbOwdUYtcPLx8s8qDQ8KiZ+MSUDZA6OSgmTCkw+DQSBYIDkFly4GgcEQ5ywKgAzMQrFA2GAthNZAplHg4fNtvo9kiUVY1kdNqcii43J5vL5-Aj7mEYJESnCxKI8pDCjCSgAWRHI1HtaygbBo6QY6Z4Hm4vT4hCE1EkjYnPG7eUi4nkdbHLb2CnwS7Um7+PkMx68tkcgrQpwlACs3Ro4nFUyxSDtMqWK32xi1pJVeu5huutJADrNTKeeDtloh1v1KgAbI6haUnejXUnPTtvfhfYdlVtZWr4GmlTryUGqSGssmI8yk2IgA
π» Code
declare const foo1: { t: 0; x: number; y: number; };
switch (foo1.t) {
case 0: throw "";
}
const _impossible1: never = foo1; // unassignable
declare const foo2: { t: 0; x: number; y: number; } | { t: 1; z: string; };
switch (foo2.t) {
case 0: throw "";
case 1: throw "";
}
const _impossible2: never = foo2; // now exhaustive somehow
This is a reduced example, but the idea is:
- there is some discriminated union type and it was narrowed elsewhere, which happens to leave only a single variant left currently
- there is a secondary narrowing, because the discriminated union is expected to get more members in the future while the first narrowing will remain unchanged
- this rather surprisingly and unintuitively causes an error
Somewhat interestingly, this is not a problem with primitives:
declare const foo3: "abc";
switch (foo3) {
case "abc": throw "";
}
const _impossible3: never = foo3;
declare const foo4: "abc" | "def";
switch (foo4) {
case "abc": throw "";
case "def": throw "";
}
const _impossible4: never = foo4;
declare const foo5: 10;
switch (foo5) {
case 10: throw "";
}
const _impossible5: never = foo5;
declare const foo6: 10 | 20;
switch (foo6) {
case 10: throw "";
case 20: throw "";
}
const _impossible6: never = foo6;
π Actual behavior
Discriminated unions rather surprisingly and unintuitively cannot be narrowed when it has only 1 member
π Expected behavior
Discriminated unions should still be narrowable when it has only 1 member, to avoid surprises
Additional information about the issue
No response
π Search Terms
narrowing, discriminated, union, member, count
π Version & Regression Information
Tested on 3.3.3333, 5.9.3, 6.0.2, and 7.0.2, all exhibit the problem.
β― Playground Link
https://www.typescriptlang.org/play/?allowUnreachableCode=true#code/CYUwxgNghgTiAEYD2A7AzgF3gMyUgjAFzwDe8GxADANzwAexKArgLYBGIMtAno6x13gBfagCg0AdwCWGMAAt4AClwEAdBgCUpUfF2IoaBJWIY5MJBPgAiK2KGjk6LAH0pLAA5I0aKWwggieBQQADdOeABeHDx8WgB6OPgmFAMfAHMUvxBRHNBIWARHTGikACZiMgp4Gno+dk4eOoFaIXgAH1JyYlj4AC9iTBgpFDSWsUkZeSUVUvUtEh09MAMjEzMLa1tF3WXDeEDTc0sbOwdUYtcPLx8s8qDQ8KiZ+MSUDZA6OSgmTCkw+DQSBYIDkFly4GgcEQ5ywKgAzMQrFA2GAthNZAplHg4fNtvo9kiUVY1kdNqcii43J5vL5-Aj7mEYJESnCxKI8pDCjCSgAWRHI1HtaygbBo6QY6Z4Hm4vT4hCE1EkjYnPG7eUi4nkdbHLb2CnwS7Um7+PkMx68tkcgrQpwlACs3Ro4nFUyxSDtMqWK32xi1pJVeu5huutJADrNTKeeDtloh1v1KgAbI6haUnejXUnPTtvfhfYdlVtZWr4GmlTryUGqSGssmI8yk2IgA
π» Code
This is a reduced example, but the idea is:
Somewhat interestingly, this is not a problem with primitives:
π Actual behavior
Discriminated unions rather surprisingly and unintuitively cannot be narrowed when it has only 1 member
π Expected behavior
Discriminated unions should still be narrowable when it has only 1 member, to avoid surprises
Additional information about the issue
No response