Home > other >  get types from array of class list
get types from array of class list

Time:01-08

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

Playground link to code

  •  Tags:  
  • Related