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
?
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.