【发布时间】:2020-01-02 21:45:54
【问题描述】:
假设我有一个为一组数据定义有效值的接口:
interface Foo {
bar: boolean;
}
而且我希望一个类能够使用方法公开该数据。我发现如果我使用keyof T 来定义键,它工作正常:
abstract class Getter<T> {
private data: T;
get<K extends keyof T>(key: K): T[K] {
return this.data[key];
}
abstract use(): void;
}
class ExtendedGetter<T extends Foo> extends Getter<T> {
use() {
this.get('bar'); // OK
}
}
但是,将键限制为仅接受带有 Extract<keyof T, string> 的字符串会导致错误:
abstract class Getter<T> {
private data: T;
get<K extends Extract<keyof T, string>>(key: K): T[K] {
return this.data[key];
}
abstract use(): void;
}
class ExtendedGetter<T extends Foo> extends Getter<T> {
use() {
this.get('bar'); // ERROR
} ~~~~~
}
'"bar"' 类型的参数不能分配给'Extract
' 类型的参数。 ts(2345)
还值得注意的是,在第二种情况下,如果直接使用Foo而不是使用扩展泛型,则不会引发错误:
class ExtendedGetter extends Getter<Foo> { ... }
为什么会这样?
导致错误的Extract<keyof T, string> 和keyof T 有什么区别?
【问题讨论】:
-
答案可能是“编译器无法识别很多可分配给未解析条件类型的内容”(如果
T是泛型类型参数而不是具体类型)。不过,我很想找到一份规范的文档来说明这一点。 -
似乎被认为是一个错误(microsoft/TypeScript#24560)
-
@jcalz 如果您将其作为答案提交,我会接受。我会一直使用
keyof T,直到该错误得到解决,假设曾经发生过。
标签: typescript