拥有Holder
类和几个实例:
class Holder<T> {
listen: (val: T) => void
};
const hs = new Holder<string>();
const hn = new Holder<number>();
和HoldersObject
类型是一个包含一堆Holder
s的对象:
type HoldersObject = { [n: string]: Holder<any> };
有没有办法正确输入combineHolders
功能,将HoldersObject
合并为一个Holder
?
function combineHolders<T extends HoldersObject>(h: T): Holder<{ [P in keyof T]: T[P] }>
const comb_1 = combineHolders({
hs,
hn,
})
// compiler yelds:
// const comb_1: Holder<{
// hs: Holder<string>;
// hn: Holder<number>;
// }>
//
// I need:
// const comb_1: Holder<{
// hs: string;
// hn: number;
// }>
需要某种ExtractGeneric<T>
,如下所示:
function combineHolders<T extends HoldersObject>(h: T):
Holder<{ [P in keyof T]: ExtractGeneric<T[P]> }>
作为一个加号,组合的持有者应该能够嵌套(但我想这应该是免费的,当解决上述问题时)
const comb_2 = combineHolders({
hs,
comb_1,
})
// compiler yelds:
// const comb_2: Holder<{
// hs: Holder<string>;
// comb_1: Holder<any>;
// }>
//
// I need:
// const comb_2: Holder<{
// hs: string;
// comb_1: {
// hs: string;
// hn: number;
// };
// }>
答案 0 :(得分:1)
通过在TypeScript 2.8中发布条件类型,可以轻松完成。 Type inference in conditional types
代码:
class Holder<T> {
listen: (val: T) => void
};
const hs = new Holder<string>();
const hn = new Holder<number>();
type HoldersObject = { [n: string]: Holder<any> };
function combineHolders<T extends HoldersObject>(h: T)
: Holder<{ [HolderName in keyof T]: T[HolderName] extends Holder<infer P> ? P : any }>
{ return undefined as any }
const comb_1 = combineHolders({
hs,
hn,
})
comb_1.listen({hs: '', hn: 0})