通过 typescript 3.0 通用休息元组类型从类元组返回实例元组

Posted

技术标签:

【中文标题】通过 typescript 3.0 通用休息元组类型从类元组返回实例元组【英文标题】:return instance tuple from classes tuple via typescript 3.0 generic rest tuples type 【发布时间】:2019-01-15 11:54:24 【问题描述】:

虽然从类类型中获取正确的实例类型,但工作方式如下:

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 功能(通用休息参数)获得正确的实例类型

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】:

我们可以让它主要在 3.0 上工作,但要获得完整的元组映射支持,我们需要等待 3.1。

要提取结果元组类型,我们可以使用映射类型和条件类型从Constructor[] 中提取结果类型。这几乎适用于 3.0。在 3.0 中,映射类型将破坏数组类型,因此在结果类型上只有索引操作仍然可以,所有方法都将是 never 类型。 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 月结束之前的某个时间发布

【讨论】:

以上是关于通过 typescript 3.0 通用休息元组类型从类元组返回实例元组的主要内容,如果未能解决你的问题,请参考以下文章

详解C# Tuple VS ValueTuple(元组类 VS 值元组)

详解C# Tuple VS ValueTuple(元组类 VS 值元组)

详解C# Tuple VS ValueTuple(元组类 VS 值元组)

详解C# Tuple VS ValueTuple(元组类 VS 值元组)

详解C# Tuple VS ValueTuple(元组类 VS 值元组)

C#关键字扫盲——Tuple(元组类) ValueTuple(值元组)