Home > database >  How to create a Typescript Set of classes inherited from a specific class?
How to create a Typescript Set of classes inherited from a specific class?

Time:08-06

I would like to create a Set of Widget-"derived" classes (not objects) in Typescript, but Set<typeof Base> doesn't seem to work when the subclasses have a constructor with any params:

class Base {}
class Child1 extends Base { constructor(id: string) { super(); } }
class Child2 extends Base { constructor() { super(); } }
const s = new Set<typeof Base>()
s.add(Child1) // fails: Argument of type 'typeof Child1' is not assignable to parameter of type 'typeof Base'
s.add(Child2) // works

Is there some way to get the limit correctly?

CodePudding user response:

You would like to say "any constructor which produces instances of a type assignable to Base". For this you'd use a construct signature of a form new (???) => Base where the ??? has to be replaced with the constructor arguments we want to support. Since you don't care about actually constructing things, you don't want to be restrictive at all. The way to say that is new (...args: any) => Base. Let's test it out:

class Base { a = 1 }
class Child1 extends Base { b = 2; constructor(id: string) { super(); } }
class Child2 extends Base { c = 3 }
const s = new Set<new (...args: any) => Base>()
s.add(Child1) // okay
s.add(Child2) // okay

class ChildBad { z = 5 }
s.add(ChildBad) // error!  
// Property 'a' is missing in type 'ChildBad' but required in type 'Base'.

Looks good.

Playground link to code

  • Related