【发布时间】:2018-08-13 02:53:50
【问题描述】:
假设我们有以下定义,我不明白为什么 TypeScript 仍然不能正确推断类型!
有人知道怎么写吗?
注意事项:
* 确保打开“严格空值检查”选项。
* 我注释了代码来解释问题,如果不清楚请评论。
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>; // evaludates to 'some' correctly
let noneType: OptionType<undefined>; // evaluates to 'none' correctly
let optionSomeValue = { option: 'some', value: 'okay' } as OptionValue<string>; // evaluates correctly
let optionNoneValue = { option: 'none', value: null } as OptionValue<null>; // evaluates correctly
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'; // type string
let someNumberValue = 22;
let someUndefinedValue: string | null | undefined = undefined;
let result1 = handleSomeValue(getValue(someStringValue)); // it is 'string' correctly
let result2 = handleSomeValue(getValue(someNumberValue)); // should be 'number' but it's 'number | empty'
let result3 = handleSomeValue(getValue(someUndefinedValue)); // it is 'empty' correctly;
【问题讨论】:
-
someValue的隐式类型为any。难道你不希望getValue(someValue)返回一个OptionValue<any>? -
根据这些文档不确定它应该以这种方式工作:typescriptlang.org/docs/handbook/release-notes/…
-
getValue的返回类型为OptionValue<T>,在调用处,T被推断为参数someValue的类型,即string | undefined。因此实例化的返回类型是OptionValue<string | undefined>。为什么你期望它是OptionValue<never>? -
你是对的。不能是
OptionValue<never>,但即使这样也无助于正确获得结果。 -
@MattMcCutchen 我更新了问题以关注您的评论。请检查一下。谢谢。
标签: javascript typescript type-inference