假设你有一个接口 GetterSetter
,它接受一个接口 M
并根据 M
存储和获取值
interface GetterSetter<M> {
get: <T extends keyof M>(key: T) => M[T];
set: <T extends keyof M>(key: T, value: M[T]) => void;
}
例如一个接口人:
interface Person {
name: string;
age: number;
}
当给 GetterSetter
时,当 get()
为 number
时,key
的返回值现在将为 'age'
现在假设您有一个 ValueSetter
类,如下所示:
class ValueSetter<S extends string, M extends { [s in S]: number }> {
constructor(
private readonly key: S,
private readonly getterSetter: GetterSetter<M>,
) {
}
method(): void {
const x: number = this.getterSetter.get(this.key);
this.getterSetter.set(this.key, 5);
}
}
它需要一个键 S,比如说 age
和一个接口 M
,这个接口肯定将键 S 映射到一个数字上。所以如果 M 是 Person
而 S 是 age
,这匹配
然而,行 this.getterSetter.set(this.key, 5);
产生以下错误:Argument of type 'number' is not assignable to parameter of type 'M[S]'.
为什么 Typescript 不暗示 M[S]
is a number
if M extends { [s in S]: number }
?
一个简单的解决方案是将这一行写成 this.getterSetter.set(this.key, 5 as M[S]);
,但我们正在寻找一种无需强制转换的解决方案