Menu

TypeScript Abstract Class: Methods, Properties, vs Interface

An abstract class in TypeScript is a base class that cannot be instantiated and can leave methods for subclasses to implement. Learn abstract methods and properties, the template method pattern, abstract constructor types, and when an interface is the better choice.

This page includes runnable editors - edit, run, and see output instantly.

An abstract class is a base class marked abstract. It cannot be created with new, and it can declare abstract methods that have no body, which every subclass must implement.

Shape shares describe() with every subclass and forces each one to supply area(). The type Shape[] holds any mix of subclasses.

An Abstract Class Cannot Be Instantiated

Calling new on an abstract class is a compile error, because the object would have methods with no implementation:

index.ts(6,11): error TS2511: Cannot create an instance of an abstract class.

This is a compile-time rule. abstract is erased from the output, so the emitted Shape is an ordinary JavaScript class, and untyped JavaScript code could still call new Shape(). When a library needs a runtime guard, the constructor can check new.target:

Abstract Methods and Properties

A subclass must implement every abstract member, or be abstract itself. Missing one is error TS2515, which reads like Non-abstract class 'Square' does not implement inherited abstract member area from class 'Shape', or TS2654 listing all of them when several are missing.

Fields, getters and methods can all be abstract, and they can be protected:

An abstract method has no body; writing one is error TS1245 (Method 'x' cannot have an implementation because it is marked abstract). An abstract class does not have to have any abstract members at all: abstract on its own just prevents direct instantiation.

The Template Method Pattern

The most common reason to write an abstract class: the base class fixes the order of the steps, and each subclass fills in the steps that vary.

Abstract classes can be generic, as here, so each subclass picks the record type.

Abstract Constructor Types

typeof Shape for an abstract class is a constructor you are not allowed to call, so a parameter typed typeof Shape cannot do new c(). When a function should accept abstract classes (for example to register them or check instanceof), type it with an abstract construct signature:

abstract new accepts both abstract and concrete classes; plain new accepts only concrete ones.

Abstract Class vs Interface

Abstract classInterface
Contains codeyes: methods, field initializers, constructorno, only types
Exists at runtimeyesno, erased
instanceofworksnot possible
A class can useone (extends)many (implements)
Access modifiersprivate, protected, publicpublic members only
Type for plain objectsonly if it has no private/protected members, and instanceof then failsyes, any value with the shape

The rule of thumb: an interface when you only need to describe a shape (the most common case, and it works for object literals too), an abstract class when subclasses share real implementation and you want the compiler to force them to fill in the gaps. The two combine well: an interface for the public contract, an abstract class as one convenient base that implements it. See interfaces vs types for the other common comparison.

Common Mistakes

  • Using an abstract class where an interface would do. If the base class has no code, it is an interface with extra runtime weight and a single-inheritance limit.
  • Trying static abstract. Not allowed. Static members cannot be abstract.
  • Expecting a runtime error from new on an abstract class. There is none unless you write the new.target check.
  • Calling an abstract method from the base constructor. It runs before the subclass's fields are initialized, so the implementation sees them as undefined.

Frequently Asked Questions

What is an abstract class in TypeScript?

A class marked abstract that cannot be created with new and may declare abstract members without an implementation. Subclasses must implement every abstract member. It is a way to share code and require a shape at the same time.

What is the difference between an abstract class and an interface in TypeScript?

An abstract class can contain real code (implemented methods, fields with initial values, a constructor) and exists at runtime, so instanceof works on it; a class can extend only one. An interface has no code, is erased at compile time, and a class can implement many. Use an abstract class to share behavior, an interface to describe a shape.

Can an abstract class have a constructor in TypeScript?

Yes. It runs when a subclass calls super(...). You still cannot call new on the abstract class itself (TS2511: Cannot create an instance of an abstract class).

Can static methods be abstract in TypeScript?

No. abstract only applies to instance members; static abstract is error TS1243 ('static' modifier cannot be used with 'abstract' modifier). To require a static shape, type the constructor with an interface that includes the static member and check the class against it.

Is an abstract class enforced at runtime?

No. abstract is erased, so the compiled class is ordinary JavaScript and plain JavaScript code could still call new on it. If that matters, check new.target in the constructor and throw.

Coddy programming languages illustration

Learn to code with Coddy

GET STARTED