如何修复打字稿查找类型中的错误?
How to fix error in lookup type for typescript?
我的问题: 我的问题的一个最小示例是 (typescript play example with the code):
enum Keys { foo = "foo", bar = "bar" }
function getValue<A extends Keys, B>(dict: { [K in A]?: B }, key: A): B | null
{
const result = dict[key]
if (result !== undefined) {
return result
} else {
return null
}
}
Typescript 对语句 return result
:
给出了以下类型检查错误
Type 'B | undefined' is not assignable to type 'B | null'.
Type 'undefined' is not assignable to type 'B | null'.
我的问题:为什么类型保护 result !== undefined
在上面的例子中不起作用,我该如何解决?
我的尝试:
- 当我检查 https://www.typescriptlang.org/play/index.html 中的示例时,我看到变量
result
的类型为 { [K in A]?: B | undefined; }[A]
。但是我希望打字稿可以自动将其减少到 B | undefined
。也许我在 A
或 dict
的类型声明中有错误,以至于打字稿无法减少查找类型...
- 当前的 nightly 版本也会出现此错误
3.9.0-dev.20200224
。
- 将类型保护更改为
typeof(result) !== "undefined"
没有帮助。
My question: What is the error in the above code example and how can I fix it? It seems that the type guard result !== undefined does not work...
"fix" 的一种方法是 return undefined
始终如一,而不是 returning null
。以下作为 API 工作,但是,正如@Austaras 正确地说的那样,它并没有有效地将类型保护中的 result
缩小到 B
。
function getValueOne<A extends Keys, B>(
dict: { [K in A]?: B },
key: A
): B | undefined {
const result = dict[key]
if (result !== undefined) {
return result; // result is { [K in A]?: B | undefined; }[A]
} else {
return undefined;
}
}
"fix" 的另一种方法是使用这样的显式类型:
function getValueToo<A extends Keys, B>(
dict: { [K in A]?: B },
key: A
): B | null {
const result: B | undefined = dict[key];
if (result) {
return result; // result is B
} else {
return null;
}
}
第三种方法可能是我最喜欢的,因为它是三种方法中最通用的。我们更改 return 类型。
function getValueThree<A extends Keys, B>(
dict: { [K in A]?: B },
key: A
): (typeof dict)[A] {
const result = dict[key]
if (result !== undefined) {
return result;
} else {
return undefined;
}
}
目前这似乎是 TSC 的错误或设计限制。它不能立即将 { [K in A]?: B | undefined; }[A]
减少到 B | undefined
,因此您可以将结果转换为 B | undefined
或将 Keys
移出 generic
const enum Keys { foo = "foo", bar = "bar" }
function get<B>(
dict: { [K in Keys]?: B },
key: Keys
): B | null {
const result = dict[key]
if (result !== undefined) {
return result
} else {
return null
}
}
另外我建议总是使用 const enum
我的问题: 我的问题的一个最小示例是 (typescript play example with the code):
enum Keys { foo = "foo", bar = "bar" }
function getValue<A extends Keys, B>(dict: { [K in A]?: B }, key: A): B | null
{
const result = dict[key]
if (result !== undefined) {
return result
} else {
return null
}
}
Typescript 对语句 return result
:
Type 'B | undefined' is not assignable to type 'B | null'.
Type 'undefined' is not assignable to type 'B | null'.
我的问题:为什么类型保护 result !== undefined
在上面的例子中不起作用,我该如何解决?
我的尝试:
- 当我检查 https://www.typescriptlang.org/play/index.html 中的示例时,我看到变量
result
的类型为{ [K in A]?: B | undefined; }[A]
。但是我希望打字稿可以自动将其减少到B | undefined
。也许我在A
或dict
的类型声明中有错误,以至于打字稿无法减少查找类型... - 当前的 nightly 版本也会出现此错误
3.9.0-dev.20200224
。 - 将类型保护更改为
typeof(result) !== "undefined"
没有帮助。
My question: What is the error in the above code example and how can I fix it? It seems that the type guard result !== undefined does not work...
"fix" 的一种方法是 return undefined
始终如一,而不是 returning null
。以下作为 API 工作,但是,正如@Austaras 正确地说的那样,它并没有有效地将类型保护中的 result
缩小到 B
。
function getValueOne<A extends Keys, B>(
dict: { [K in A]?: B },
key: A
): B | undefined {
const result = dict[key]
if (result !== undefined) {
return result; // result is { [K in A]?: B | undefined; }[A]
} else {
return undefined;
}
}
"fix" 的另一种方法是使用这样的显式类型:
function getValueToo<A extends Keys, B>(
dict: { [K in A]?: B },
key: A
): B | null {
const result: B | undefined = dict[key];
if (result) {
return result; // result is B
} else {
return null;
}
}
第三种方法可能是我最喜欢的,因为它是三种方法中最通用的。我们更改 return 类型。
function getValueThree<A extends Keys, B>(
dict: { [K in A]?: B },
key: A
): (typeof dict)[A] {
const result = dict[key]
if (result !== undefined) {
return result;
} else {
return undefined;
}
}
目前这似乎是 TSC 的错误或设计限制。它不能立即将 { [K in A]?: B | undefined; }[A]
减少到 B | undefined
,因此您可以将结果转换为 B | undefined
或将 Keys
移出 generic
const enum Keys { foo = "foo", bar = "bar" }
function get<B>(
dict: { [K in Keys]?: B },
key: Keys
): B | null {
const result = dict[key]
if (result !== undefined) {
return result
} else {
return null
}
}
另外我建议总是使用 const enum