使用带有默认(空(compilerOptions
的 Typescript v2.4.1 .
我知道通常泛型可用于将函数或类方法的返回类型限制为与传递的参数相同的类型。但是,我知道keyof
提供了更多的功能,我正在尝试使用它来约束类方法的返回类型与存储的属性值相同。
最后一行(分配给x(给了我以下编译错误(似乎与类型扩大有关(:
类型"字符串|数字"不能分配给类型"字符串"。
类型">数字"不能分配给类型"字符串"。
// vim: set et sw=4 ts=4 ff=unix ft=javascript :
class Store<S, K extends keyof S> {
private store: S;
constructor(storeDefaults: S) {
this.store = storeDefaults;
}
get(key: K): S[K] {
return this.store[key];
}
}
const store = new Store({
x: 'hello',
y: 7,
});
const x: string = store.get('x'); // should succeed, but shows an error
//const y: string = store.get('y'); // should fail as y is a number
有谁知道如何实现这一目标(如果可以实现(,或者如果不是,应该如何使用keyof
?
发生这种情况是因为参数类型是在构造Store
解析的,这对于get
方法对于任何类型的键来说都无法正常工作有点"太早"。创建的存储K
专门解析为最广泛的可能类型K = keyof S = "x" | "y"
,其中存储状态的可能值"string" | "number"
。有关从键类型到值类型的映射的信息在此过程中丢失。
如果将泛型类型K
移动到方法,编译器将在每次特定调用时对其进行计算,从而清除歧义。
class Store<S> {
private store: S;
constructor(storeDefaults: S) {
this.store = storeDefaults;
}
get<K extends keyof S>(key: K): S[K] {
return this.store[key];
}
}
const store = new Store({
x: 'hello',
y: 7,
});
const x: string = store.get('x'); // ok!