打字稿:从泛型中提取类型

时间:2018-02-23 15:30:47

标签: typescript-typings

拥有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;
//     };
// }>

1 个答案:

答案 0 :(得分:1)

通过在TypeScript 2.8中发布条件类型,可以轻松完成。 Type inference in conditional types

ts playground

代码:

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})