In Typescript we have way to access types from array as below.
const list = [item,item2] as const;
type typeOfArray = typeof list[number];
const something: typeOfArray = ; // item | item2
I have attempted to get that with class but getting "Property 'prototype' is missing in type error"
If I declare classes as type it works fine but can't access through typeof
. Is this shortcoming of Typescript? If you have solution, will appreciate your help.
please use below code as sample setup:
class A {
methodA() {
}
}
class B {
methodB() {
}
}
class C {
methodC() {
}
}
const classList = [A,B,C] as const;
This works just fine:
type classSelection = A | B | C;
let o: classSelection;
o = new A();
o. // o.methodA;
This is giving above error:
type classSelection = typeof classList[number];
o = new A(); //Type 'A' is not assignable to type 'typeof A | typeof B | typeof C'.
Property 'prototype' is missing in type 'A' but required in type 'typeof C'
CodePudding user response:
Your classList
variable is an array of class constructors:
const classList = [A, B, C] as const;
// const classList: readonly [typeof A, typeof B, typeof C]
Which means when you index into its type with a number
key type, you get a union of those constructor types:
type ClassConstructors = typeof classList[number];
// type ClassConstructors = typeof A | typeof B | typeof C
Class constructors are not themselves instances; instead, they have construct signatures that look like {new (): A}
(which means that using the new
operator on it with no arguments will yield a value of type A
).
There is an InstanceType<T>
utility type which takes a type with a construct signature and returns the corresponding instance type. If you apply it to a union of constructor types, you get a union of instance types:
type ClassSelection = InstanceType<typeof classList[number]>;
// type ClassSelection = A | B | C
And then the rest of your code should work:
let o: ClassSelection = new A(); // okay