I have searched a lot and read several question to find a solution to my problem but in no vain. Can you help me?!
What I don't understand is that when a type extends boolean and put in the if statement condition it should be narrowed to true but TypeScript has a different idea in some situation:
import Select from "react-select";
export interface Option<Value> {
readonly value: Value;
readonly label?: string;
readonly isDisabled?: boolean;
readonly isFixed?: boolean;
}
export type PropValue<Value, IsMulti extends boolean> = IsMulti extends true
? Value[]
: Value;
const ComboBox = <Value, IsMulti extends boolean>(props: {
value?: PropValue<Value, IsMulti>;
options: Option<Value>[];
isMulti: IsMulti;
}) => {
const { value, isMulti, options } = props;
const mapValue = (x?: PropValue<Value, IsMulti>) => {
if (!x) return undefined;
if (isMulti) {
isMulti;
// ??? why isMulti is not of type `true` but rather still `extends boolean`
// ??? x should be an array but doesn't seem to be narrowed as well
return options.filter(({ value }) => x.includes(value));
}
};
return <Select value={mapValue(value)} isMulti={isMulti} />;
};
A more simple scenario will work as expected:
function experimenting<T extends boolean>(x: boolean, y: T) {
if (x) {
x; //: true
}
if (y) {
y; //: true
}
}
- Can you explain
isMultiin the first scenario didn't get narrowed to justtrue? - How to fix the code above so that both
isMultiandxare narrowed.
T extends booleandoesn't mean thatTis equal toboolean. The extends clause just means thatTis a subset of thebooleanand the compiler isn't able to narrow the type to justtruesince it doesn't know the exact type of it.Example:
neveris an empty set and the subsets of thebooleanaretrue|false|never, since an empty set is also a subset. Thus, we can passneverto the function that expects a generic parameter that extendsboolean: