确保对象的所有成员都实现某个版本的通用接口

时间:2017-02-02 19:12:15

标签: typescript

TypeScript索引签名类型是否可以声明每个索引都实现了某个版本的泛型接口?我想写这样的代码:

interface HasState<T> {
  state : T;
}

interface ModuleDefinition {
  [moduleName : string] : <T>HasState<T>;
}

这是我的用例:

我有一个对象的TypeScript映射类型:

interface ModuleDefinition {
  [moduleName : string] : HasState;
}

interface HasState {
  state : any;
}

此代码确保ModuleDefinition对象中的每个值都具有名为state的参数。

但是,如果我使用此映射类型尝试解包状态对象:

type UnwrappedModules<Mod extends ModuleDefinition> = {
  [K in keyof Mod] : Mod[K]["state"];
}

并声明并使用函数

function unwrap<Mod extends ModuleDefinition>(mod: Mod) : UnwrappedModules<Mod> {
  // ...
}

const result = unwrap({
  apple: {
    state: {
      color: 'red'
    }
  }
}).apple

result类型为any,而不是{ color : string },就像我期望的那样。有没有办法让TypeScript在这里推断出正确的类型?

1 个答案:

答案 0 :(得分:0)

是的,你可以这样做!解决方案是向后看问题:即使你不能使用解包,也可以使用映射类型 wrap

type StateWrapped<T> = {
  [K in keyof T]: HasState<T[K]>;
}

而不是您的unwrap()函数接受普通类型T的输入并返回未解包的T,而是可以输入 wrapped { {1}}并返回普通T

T

这是所有类型检查,并且具有您正在寻找的结果:

function unwrap<T>(mod: StateWrapped<T>): T {
  var ret = {} as T;
  for (var k in mod) {
    ret[k] = mod[k].state;
  }
  return ret;
}

希望有所帮助!