Infer constructor type in TypeScript
Asked Answered
G

3

8

Is it possible to infer the constructor type of a class in TypeScript? I tried this but it seems not to work:

type Constructor<K> = K extends { new: infer T } ? T : any;
Gawky answered 26/4, 2019 at 11:16 Comment(3)
What about: type Constructor<K> = K extends { new: () => infer T } ? T : any;Gilberte
class Foo {}, type CtorOfFoo = typeof FooEurhythmic
Can you edit this to show a minimal reproducible example of what you're trying to accomplish?Egin
F
6

There is already a predefined conditional type that allows you to extract the instance type from a class type, called InstanceType

class A { private x: any}

type AInstance = InstanceType<typeof A> // same as A

The definition of this type is:

type InstanceType<T extends new (...args: any) => any> = T extends new (...args: any) => infer R ? R : any;
Flatt answered 26/4, 2019 at 12:5 Comment(3)
Looks interesting but unfortunately, I need it the other way around.Gawky
@MarkusMauch not clear what you mean, you need to get the class type based on the instance type ? Don't think that information is accessible from the instance typeFlatt
Yeah, it's a known issue that a class instance doesn't have a strongly-typed constructor property. So unless you just want to get Function, you're probably stuck with new (...args: any) => T unless you manually strengthen the constructor property on all the classes you care about.Egin
P
1

Instead of trying to infer it, can you refer to class types by their constructor functions like this?

type Constructor<K> = { new(): K };

const x: Constructor<String> = String; 

const s = new x();
Perfumer answered 26/4, 2019 at 11:58 Comment(0)
C
0

In most cases, doing typeof ClassA is what you need. But you can also create a util type to manually infer the constructor type

type Constructor<T extends new (...args: any) => any> = T extends new (...args: infer A) => infer R ? new (...args: A) => R : neverÏ
Colp answered 9/11, 2022 at 6:57 Comment(0)

© 2022 - 2024 — McMap. All rights reserved.