TypeScript
TypeScript copied to clipboard
Type narrowing with union types create impossible case with else statement
🔎 Search Terms
else type narrowing
🕗 Version & Regression Information
- This is the behavior in every version available on the typescript playground, and the FAQ doesn't seem to mention it
- EDIT: it only seems to happen when there are more type unions within the type union
⏯ Playground Link
EDIT: this is a bad example https://www.typescriptlang.org/play/?ts=5.4.5#code/C4TwDgpgBAQgrgcygXigbwFBW1AhgLigHIAeZIgGixwCNCA7OAWxogCcMBfKAH3WuwFiAPnJUcUAMYNmrDpwwYA9EqgATAPYQAzvSLAoAdw1sA1gH4MkjfW0HgO4IXhJUmCUNJiBUOlABMXBgAlgBmUAAUDnYAdLgoqF5EAJT8Eiq+UBAAHsF22nj0alJSuPT0GsA+1rYaADYQMXUaCFGOMTTJ1Tba9Y3NrdHAMZJd3BB12tDuOBnB9FC9TNCSuFMFwAAW7NB5eFAARNZMYLhseTZ4YJBnBXD08w70wME2uHUHWWxsJlBhUABJKDANggYEaKQaE5naBDOI+DL0CDBLbsEq-GhZXJ2KDbNjQCAANwgCy2GkQm32TDgONYInIhWKqPxoRMKyg1JxOTyVQkNV6DSaLTasU63VqgoGIuGoyCylUNDg9k2e2MZm0GFC90kL0uQ38UWciFSM2w-yicQSxDIKTSEhw-L6QsGHS6EnGk2mPj5PSdUplbpwCk4QA
💻 Code
EDIT: still a bad example, assume test
is not known
type Bug = {
a: '<=',
b: number
} | {
a: '>=',
c: number
}
// doesn't work?
const test: Bug = {
a: '<=',
b: 2
}
if (test.a == '<=') {
// b exists and c cannot
console.log(test.b)
console.log(test.c)
} else {
// in some cases there is a "comparison appears unintentional" error if I try to compare test.a
// neither c or b exist here even though a must be '>=' and therefore c must exist
console.log(test.b)
console.log(test.c)
}
// but this works
function test2(t: Bug) {
if (t.a == '<=') {
console.log(t.b)
} else {
console.log(t.c)
}
}
🙁 Actual behavior
else
statement does not type narrow properly in some cases.
In my code it's impossible to get around this as the type narrowing DOES work properly in further if statements, which prevents me from simply checking with the same comparison again with a return statement.
The example given uses the value of a
to determine whether to use b
or c
, but the narrowing doesn't allow any code in the else
to use either.
🙂 Expected behavior
The type narrowing checks for the if
condition inside the else
block should also apply to other code in the else
block.