Lets say I have a base class A and A1, A2, A3 all extends A. I create a factory class say, FactoryForA that implements a method say getObject as
getObject(typeToSwitch) {
case A1: // return an object of A1
case A2: // return an object of A2
case A3: // return an object of A3
}
I am looking for a way to make the argument typeToSwitch type safe.
My approach would be using infer typescript keyword to return the requested type. Something like the below:
class A {
public getA = () => {}
}
class A1 extends A {
constructor() { super(); }
public getA = () => { return 'A1'; }
}
class A2 extends A {
constructor() { super(); }
public getA = () => { return 'A1'; }
}
// get the key map types ( a1 and a2 )
type Keys = keyof typeof FactoryA.AMap;
// get the classes types
type aTypes = typeof FactoryA.AMap[Keys];
// build the return type with generics
type ClassInstanceType<T> = T extends new () => infer R ? R : never;
class FactoryA {
public static AMap = { a1: A1, a2: A2 };
public static getObject = (typeToSwitch: Keys ): ClassInstanceType<aTypes> => {
return new FactoryA.AMap[typeToSwitch]();
}
}
const a1instance: A1 = FactoryA.getObject('a1');
console.log(a1instance.getA());
What I came up with is getObject<T extends new(...args: any[]) => A>(typeToSwitch: T).
It says T is something that extends A and is constructible, so it allows us to use a type as value(I am yet to figure this why). Also getObject(T extends A) does not work(why only a constructible type is supported.)
If anyone has suggestions or explanations please update the answer or comment.
Here is a link to an example of what I said above.