A TypeScript class inherits from another with extends. The subclass gets every field and method of the parent, calls the parent constructor with super(...), and can override methods, and TypeScript checks that each override stays compatible with the parent's types.
This is JavaScript class inheritance (see inheritance in JavaScript for the prototype chain behind it). TypeScript adds the type checks: a Dog is assignable anywhere an Animal is expected, and the compiler verifies the override and the super call.
Overriding Methods
A subclass method with the same name replaces the parent's. Its type must be assignable to the parent's: same or compatible parameters, same or narrower return type. Otherwise any code holding an Animal could call the method with arguments the subclass cannot handle.
Changing the parameter to value: string would be error TS2416: Property 'format' in type 'CurrencyFormatter' is not assignable to the same property in base type 'Formatter'. The loop shows why: it calls format with a number on every element, without knowing which subclass it has.
There is one hole. Method parameters are compared bivariantly, so an override that accepts a narrower type, such as format(value: 1 | 2), compiles even though the loop could still pass it 1234567. Return types are checked strictly: returning number instead of string is TS2416.
The override Keyword and noImplicitOverride
override says "this member replaces one in the base class", and the compiler holds you to it. If the base has no such member (a typo, or a method someone renamed in the parent), it is an error:
index.ts(9,14): error TS4117: This member cannot have an 'override' modifier because it is not declared in the base class 'Animal'. Did you mean 'speak'?
Without override, that typo compiles and speak() silently returns "...". The keyword only helps where it is written, so turn on noImplicitOverride in tsconfig.json. Then every method that overrides a base member must say so, and a plain speak() in a subclass is error TS4114 (This member must have an 'override' modifier because it overrides a member in the base class 'Animal').
{
"compilerOptions": {
"strict": true,
"noImplicitOverride": true
}
}
noImplicitOverride is not part of strict; you have to add it yourself. override is erased from the compiled JavaScript.
protected Members in Subclasses
private members of the parent are invisible in the subclass. protected members are visible, which is the reason protected exists: it is the API a parent class offers to its children.
See access modifiers for the full rules, including why neither private nor protected is enforced at runtime.
Redeclaring a Field with a Narrower Type
A subclass often knows a field holds something more specific than the parent says. Redeclaring it as pet: Dog has a runtime effect with modern class fields: the subclass field is initialized to undefined after super() returns, wiping out what the parent constructor stored. Unless the subclass constructor assigns it again, TypeScript reports this as TS2612 (Property 'pet' will overwrite the base property in 'Home'). Use declare to change only the type:
declare emits nothing, so the value set by Home's constructor survives. The constructor that only accepts a Dog is what makes the narrower type true.
implements vs extends
The two keywords answer different questions, and a class can use both.
extends | implements | |
|---|---|---|
| Works with | one class | any number of interfaces (or type aliases of object types) |
| Brings code | yes: fields, methods, constructor | no, it only checks the shape |
| Exists at runtime | yes, the prototype chain | no, erased |
instanceof works | yes | no |
| Typical use | share real behavior | promise a shape to the rest of the code |
A class can extend only one class (TS1174: Classes can only extend a single class). To combine behavior from several places, implement several interfaces and share code through composition (a field holding a helper object) or mixins.
Mixins
A mixin is a function that takes a class and returns a subclass of it. It gives a form of multiple inheritance that type-checks:
The any[] in Constructor is required: TypeScript only accepts a mixin base whose constructor takes a single rest parameter of type any[]. Mixins work but make types and stack traces harder to read, so reach for composition first.
Common Mistakes
- Calling an overridable method from the base constructor. The base constructor runs before the subclass's fields are initialized, so an override that reads
this.itemsseesundefined, and a call likethis.items.push(x)throws aTypeErrorat runtime. TypeScript does not catch this. - Forgetting
super(...)or calling it late. ErrorsTS2377andTS17009; the parent must build the object before the subclass touchesthis. - Redeclaring a parent field without
declare. The subclass field resets it toundefined. - Deep hierarchies. Every level couples the child to the parent's internals. Two levels is usually plenty; prefer composition or interfaces beyond that.
Frequently Asked Questions
How does inheritance work in TypeScript?
A class inherits from another with extends: class Dog extends Animal. The subclass gets the parent's fields and methods, calls the parent constructor with super(...), and can override methods. TypeScript checks that overrides stay type-compatible with the parent.
What does the override keyword do in TypeScript?
override marks a method or property that replaces one from the base class. If the base class has no member with that name, the compiler reports TS4117, which catches typos and members renamed in the parent. With noImplicitOverride on, every override must carry the keyword (TS4114 otherwise).
How do I call a parent class method in TypeScript?
Use super.methodName(...) inside the subclass method. In the constructor, super(...) calls the parent constructor and must run before any use of this.
Does TypeScript support multiple inheritance?
No. A class can extend only one class (TS1174: Classes can only extend a single class). It can implement any number of interfaces, and mixins (functions that take a class and return a subclass) combine behavior from several sources.
What is the difference between extends and implements?
extends inherits real code from a parent class. implements only checks that a class matches an interface's shape and adds nothing at runtime. A class can do both: class Dog extends Animal implements Pet.