I’m working with TypeScript 5, and I’m having trouble with type narrowing when using a boolean flag to determine the shape of an object. I expected TypeScript to be able to correctly infer the types, but I’m getting a type error.
Here’s a simplified version of my code:
type Input = {
isMulti: true,
value: string[]
} | {
isMulti: false,
value: string
}
function multi({ isMulti, value }: Input) {
if (isMulti) {
return value[0];
}
return value;
}
function test(incomingMulti: boolean) {
const value = incomingMulti ? ['1'] : '1';
return multi({ isMulti: incomingMulti, value });
}
Playground
I’m getting the following error on the line where I call the multi
function:
Argument of type '{ isMulti: boolean; value: string | string[]; }' is not assignable to parameter of type 'Input'.
Type '{ isMulti: boolean; value: string | string[]; }' is not assignable to type '{ isMulti: false; value: string; }'.
Types of property 'isMulti' are incompatible.
Type 'boolean' is not assignable to type 'false'.
I assumed that TypeScript would be able to infer the correct type based on the value of isMulti
:
- if
true
:value
isstring[]
- if
false
:value
isstring
- if
boolean
:value
isstring | string[]
However, it seems to be arbitrarily choosing the false
path.
Interestingly, this works:
function test2(incomingMulti: boolean) {
if (incomingMulti) {
multi({ isMulti: true, value: ['1'] });
} else
multi({ isMulti: false, value: '1' });
}
but I don’t want to force the developers to write it like that every time.
1