What type should I use in typescript to represent any class?
I'm trying to write a function that takes an array of classes and returns an array with different order.
function shuffle(classes: typeof Object[]) : typeof Object[] {
return ...;
}
class A { }
class B extends A { }
class C extends B { }
class D extends B { }
suffle([A, B, C, D]);
Argument of type 'typeof A[]' is not assignable to parameter of type 'ObjectConstructor[]'.
Then I've tried:
shuffle([typeof A, typeof B, typeof C, typeof D]);
error TS2345: Argument of type 'string[]' is not assignable to parameter of type 'ObjectConstructor[]'. Type 'string' is not assignable to type 'ObjectConstructor'.
What's the right way? Generics? How? This doesn't work:
export function <T extends typeof Object> shuffle(classes: T[]) : T[]
This neither:
export function <T extends Object> sortClassesBySpeciality(classes: typeof T[]) : typeof T[]
Also why Ok, got this, typeof (typeof A)
is "string"
and "" + typeof A
is function
?typeof
has two very different meanings context of type definition and expression.
(The ultimate goal is to sort the classes by level of extends
from Object
.)
You should avoid using the type Object
in typescript, you better use any
as the docs say:
You might expect Object to play a similar role, as it does in other languages. But variables of type Object only allow you to assign any value to them - you can’t call arbitrary methods on them, even ones that actually exist
But if you want to represent classes then you need to have the following form:
{ new (): CLASS_TYPE }
Or in your case:
function shuffle(classes: Array<{ new (): any }>): Array<{ new (): any }> {
return [];
}
class A { }
class B extends A { }
class C extends B { }
class D extends B { }
shuffle([A, B, C, D]);
(code in playground)
If all of your classes are based on a super class (as your example implies) then you can simply do:
function shuffle(classes: Array<{ new (): A }>): Array<{ new (): A }> {
return [];
}
Just saw that you want to
sort the classes by level of extends from Object
To answer that:
function shuffle(classes: Array<{ new (): any }>): Array<{ new (): any }> {
return classes.sort((a, b) => getInheritanceLevel(a) - getInheritanceLevel(b));
}
function getInheritanceLevel(cls: { new (): any }): number {
let level = 0;
while (Object.getPrototypeOf(cls.prototype) !== Object.prototype) {
level++;
cls = Object.getPrototypeOf(cls.prototype).constructor;
}
return level;
}
shuffle([D, A, C, B]); // returns [A, B, D, C]
(code in playground)
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With