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在这里推断出正确的类型?
答案 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;
}
希望有所帮助!