繁体   English   中英

Typescript Generics keyof参数签名

[英]Typescript Generics keyof parameter signature

我很难过,希望这个简化的例子能很好地解释它:

我有一个 class 实例保存数据,还有另一个复合 class 实例来呈现数据。 数据 class 为 UI class 提供回调,以获取和设置数据属性。 我也被“set”难住了,但我现在会坚持使用“getVal”。

class Person {
  private _data: DataObj

  constructor() {
    this._ui = new PersonUI({
      getVal: (key) => this.getVal(key)
    })
  }

  getVal<T extends keyof DataObj>( key: T ) {
    return this._data[key]
  }
}

class PersonUI {
  constructor(arg: UIArg) {}
}

Typescript 可以推断 _data 值的类型,但我不知道如何为 UIArg 编写一个接口来保持推断的类型,我能想到的只是“任何”例如:

interface UIArg {
  getVal: <T extends keyof DataObj>(key: T) => any
}

有没有办法编写接口来保持推断的类型?

奖励问:有没有办法编写 Person.p.setVal 方法来使用推断类型? 前任:

setVal<T extends keyof DataObj>(key: T, val: any) {
  this._data[key] = val
}

您正在寻找索引访问类型 如果您有一个类型T和一个键类型K extends keyof T ,那么该键的属性将具有类型T[K]的值。 在您的情况下, DataObj扮演T的角色,我将使用K来表示键类型(比T更惯用)......所以有问题的值类型是DataObj[K]

interface UIArg {
    getVal: <K extends keyof DataObj>(key: K) => DataObj[K],
    setVal: <K extends keyof DataObj>(key: K, val: DataObj[K]) => void;
}

class Person {
    private _data: DataObj
    private _ui: PersonUI;
    constructor(data: DataObj) {
        this._data = data;
        this._ui = new PersonUI({
            getVal: key => this.getVal(key),
            setVal: (key, val) => this.setVal(key, val)
        })
    }

    getVal<K extends keyof DataObj>(key: K): DataObj[K] {
        return this._data[key]
    }

    setVal<K extends keyof DataObj>(key: K, val: DataObj[K]) {
        this._data[key] = val
    }

}

这编译没有错误。

Playground 代码链接

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM