打字稿不会推断扩展接口中的值类型

时间:2021-07-28 12:05:50

标签: typescript generics types interface

假设你有一个接口 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]);,但我们正在寻找一种无需强制转换的解决方案

0 个答案:

没有答案