通过typescript 3.0通用rest元组类型从类tuple返回实例元组

时间:2018-08-08 09:16:43

标签: typescript tuples typescript-generics typescript3.0

从类类型获取正确的实例类型时,其工作方式如下:

type Constructor<T = {}> = new (...args: any[]) => T

class Foo {}

function getInstanceFromClass<T>(Klass: Constructor<T>): T {
  return new Klass()
}

// $ExpectType Foo
const fooInst = getInstanceFromClass(Foo)

我没有弄清楚如何通过新的TS 3.0功能(通用的rest参数)获得正确的实例类型

class Foo {}
class Test {}

function getInstancesFromClasses<T extends Constructor[]>(...klasses: T): T { 
  return klasses.map(klass => new klass()) as any
}

// $ExpectType [typeof Foo, typeof Test]
const instances = getInstancesFromClasses(Foo,Test)

but what I need is 
// $ExpectType [Foo, Test]

1 个答案:

答案 0 :(得分:0)

我们可以使它主要在3.0上运行,但是要获得完整的元组映射支持,我们将需要等待3.1。

要提取结果元组类型,我们可以使用映射和条件类型从Constructor[]中提取结果类型。这几乎可以在3.0中使用。在3.0中,映射类型将破坏数组类型,以便仅索引操作在结果类型上仍然可以,所有方法的类型都从不。 3.1将使元组和数组上的映射类型按预期工作(更多信息,请阅读PR)。

type Constructor<T = {}> = new (...args: any[]) => T

class Foo {}
class Test {}

type InstanceTypes<T> = {
    [P in keyof T] :T[P] extends Constructor<infer U> ? U : never
}

function getInstancesFromClasses<T extends Constructor[]>(...klasses: T): InstanceTypes<T> { 
return klasses.map(klass => new klass()) as any
}

const instances = getInstancesFromClasses(Foo,Test)
let foo = instances[0] // is Foo
let bar = instances[1] // is Test

let [foo1, bar2] = instances // error in 3.0 since the mapped type is not really a tuple will work in 3.1

注意,您已经可以通过从npm(npm install typescript@next)安装来测试它在3.1中是否可以正常运行。 3.1将于2018年8月底之前的某个时间发布