Typescript泛型-将接口密钥用于另一种密钥类型

时间:2020-09-16 19:11:43

标签: javascript typescript typescript-typings typescript-generics

很难解释我要实现的目标(不确定是否可行),因此这里的代码是:

interface CellConfig {
  btn?: cellBtn;
  ...
}
interface CellBtn {
  isEnabled?: boolean;
  label?: string;
  style?: any;
  classes?: any;
}
interface DataSet {
  position: number;
  name: string;
  weight: string;
  symbol: string;
  config?: *missing part, not sure how to do it*
}

所以我想要这样的东西:

let dataSet: DataSet = {
  position: 1,
  name: 'test',
  weight: '11',
  symbol: '123',
  config: { position: { btn: {isEnabled: true }}, name: { btn: { isEnabled: true }}}
}

基本上,config应该是可选对象,并且只允许使用DataSet键(config除外),并且配置对象中的每个键都应为CellConfig类型

2 个答案:

答案 0 :(得分:3)

为了便于构造DataSet,我可能会将接口分成非config属性,如下所示:

interface BaseDataSet {
    position: number;
    name: string;
    weight: string;
    symbol: string;
}

然后使用mapped DataSet属性使config扩展它:

interface DataSet extends BaseDataSet {
    config?: { [K in keyof BaseDataSet]?: CellConfig }
}

您可以验证其行为是否符合您的示例预期。

Playground link to code

答案 1 :(得分:1)

这是@jcalz答案更复杂的方法,它避免了创建新类型(尽管以可读性为代价)

由于您使用的是interface,因此可以使用this访问完整类型,然后使用config排除Exclude<keyof this, "config">以获取类型为{{1}的类型},使用config创建CellConfig s的对象,并使用Record<keyof Exclude<keyof this, "config">, CellConfig>使所有对象可选:

Partial<Record<Exclude<keyof this, "config">, CellConfig>>