简体   繁体   中英

return instance tuple from classes tuple via typescript 3.0 generic rest tuples type

While getting proper instance type from class type works like following:

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)

I didn't figure out how to get proper instance type with new TS 3.0 feature ( Generic rest parameters )

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]

We can get this to mostly work on 3.0, but for full tuple mapping support we will need to wait for 3.1.

To extract the result tuple type we can use a mapped and a conditional type to extract the result type from the Constructor[] . This almost works in 3.0. In 3.0 the mapped type will mangle the array type so that only indexing operations will still be OK on the resulting type, all methods will be of type never. 3.1 will make mapped types on tuples and arrays work more as expected (read PR for details) .

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

Note You can already test that this works fully in 3.1 by installing from npm ( npm install typescript@next ). 3.1 is due for release sometime before the end of august 2018

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM