Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Infer arguments for abstract class in typescript

I'm trying to get the arguments for typescript classes and functions.

export type CtorArgs<TBase> = TBase extends new (...args: infer TArgs) => infer Impl ? TArgs : never;
export type AbsCtorArgs<TBase> = TBase extends {constructor: (...args: infer TArgs) => infer Impl} ? TArgs : never;
export type FuncArgs<TBase> = TBase extends (...args: infer TArgs) => infer Impl ? TArgs : never;

function RegularFunction(a:string,b:number){}
class RegularClass{
    constructor(a:string,b:number){}
}    
abstract class AbstractClass{
    constructor(a:string,b:number){}
}


type thing = [
    CtorArgs<typeof RegularClass>,
    FuncArgs<typeof RegularFunction>,
    AbsCtorArgs<typeof AbstractClass>,
    CtorArgs<typeof AbstractClass>,
    FuncArgs<typeof AbstractClass>
];

But for some reason abstract classes don't return arguments of their constructors. Returns only never I suspect this is because the new keyword isn't available on abstract classes. Does anybody know how to get those arguments which do actually exist for an abstract class constructor?

And no, this isn't about instantiating a abstract classes, this is about dependency injection to a class that inherits from an abstract class and the arguments to that class. See here

like image 895
DrSammyD Avatar asked Nov 16 '22 02:11

DrSammyD


1 Answers

It is possible to infer parameters of abstract class. You just need to add abstract keyword before new.

See example:


abstract class AbstractClass {
    constructor(a: string, b: number) { }
}
export type InferAbstract<T> = T extends abstract new (...args: infer Args) => infer _ ? Args : never;

type Result = InferAbstract<typeof AbstractClass> // [a: string, b: number]

But you don't even need to use some custom utility types. You can use built it [ConstructorParameters][1] which was introduced in TS 3.1

like image 196
captain-yossarian Avatar answered Dec 05 '22 05:12

captain-yossarian