Consider the following definitions- I am confused why TypeScript fails to infer the types correctly.
If you have a solution, please share!
Important Notes:
* Ensure that the "Strict Null Check" option is enabled.
* The code includes comments for clarity; feel free to ask if anything is unclear.
type Diff<T, U> = T extends U ? never : T;
type NotNullable<T> = Diff<T, null | undefined>;
type OptionType<T> = T extends NotNullable<T> ? 'some' : 'none';
interface OptionValue<T> {
option: OptionType<T>;
value: T;
}
let someType: OptionType<string>;
let noneType: OptionType<undefined>;
let optionSomeValue = { option: 'some', value: 'okay' } as OptionValue<string>;
let optionNoneValue = { option: 'none', value: null } as OptionValue<null>;
let getValue = <T>(value: T): (T extends NotNullable<T> ? OptionValue<T> : OptionValue<never>) =>
({ option: value ? 'some' as 'some' : 'none' as 'none', value });
let handleSomeValue = <T>(obj: OptionValue<T>) => {
switch (obj.option) {
case 'some':
return obj.value;
default:
return 'empty' as 'empty';
}
}
let someStringValue = 'check';
let someNumberValue = 22;
let someUndefinedValue: string | null | undefined = undefined;
let result1 = handleSomeValue(getValue(someStringValue));
let result2 = handleSomeValue(getValue(someNumberValue));
let result3 = handleSomeValue(getValue(someUndefinedValue));
Playground link