typescripttypessuperclass

Get Superclass type of TypeScript class?


Given

class Foo {
  x = 1;
  y = 2;
}
class Bar extends Foo {
  override x = 11;
  z = 3;
}

Is it possible to derive Foo given Bar automatically? Like Superclass<Bar> === Foo ?


Solution

  • There's unfortunately no way to do this that doesn't involve actually mentioning Foo manually.


    It's not possible to write a utility type that accepts the instance type Bar and produces Foo from it, so there's no way to write type Superclass<T> = ⋯. That's because the type named Bar doesn't really know anything about Foo. TypeScript's type system is structural and not nominal. TypeScript cares about the shape or structure of a type, such as the properties of an object type. It does not care about the name or the declaration of the type. Your Bar is therefore completely equivalent to

    interface MyBar {
        x: number,
        y: number,
        z: number
    }
    
    var v: Bar; 
    var v: MyBar; // okay
    

    (Note that TypeScript allows you to redeclare the var v as both Bar and MyBar, which is evidence that it considers those to be identical types. Otherwise there would have been a compiler error saying that subsequent declarations must be the same type.) And since the MyBar type doesn't have anything to do with Foo (there's no way to discern which, if any, of the properties of MyBar might have come from somewhere else), then neither does the Bar type.

    Structural typing places some limits on the kinds of things you can do in the type system, and this is one such limit.


    One might hope that at least inside of the body of the Bar class statement you'd be able to refer to the type of super programmatically, but this is also not possible. There is no "polymorphic super type" that works like the polymorphic this type. I didn't find any existing feature requests in the TypeScript GitHub repository issues; if you really need this you might consider filing a request, but given that the workaround today is just "use Foo instead of super" and nobody else is asking for this, it's unlikely that such a request would be implemented.

    Playground link to code