This error occurs when a method in an abstract class is declared without an implementation body and is not marked as abstract. TypeScript requires every method to either have a function body or be explicitly declared as abstract within an abstract class. Understanding this rule prevents compilation errors and ensures proper interface contracts in your class hierarchy.
In TypeScript, when you declare a method within a class marked as abstract, every method must follow one of two rules: it either has a complete implementation (a function body with curly braces), or it is marked with the abstract keyword to indicate that subclasses must provide the implementation. This rule enforces that abstract classes act as contracts—they cannot have incomplete method declarations that dangle without either being implemented or explicitly marked as abstract. When you violate this rule, TypeScript refuses to compile, showing this error. The purpose is to ensure clarity: other developers know immediately whether a method is meant to be a template (abstract) or already has working code (implemented).
Find the method that triggers the error. It will look like a method signature without a body and without the abstract keyword. The error message tells you the exact method name and class.
You have two options:
Option 1: Add a method body (implementation)
abstract class Animal {
// WRONG - missing body and abstract keyword
makeSound();
// CORRECT - has implementation
makeSound() {
console.log("Generic animal sound");
}
}Option 2: Mark the method as abstract
abstract class Animal {
// WRONG - missing abstract keyword and body
makeSound();
// CORRECT - marked abstract, no body needed
abstract makeSound(): void;
}Choose Option 1 if the method should have default behavior that all subclasses can use. Choose Option 2 if each subclass must provide its own implementation.
When you mark a method as abstract, every non-abstract class that extends your abstract class must implement that method. If you forget, TypeScript will show an error on the subclass.
abstract class Animal {
abstract makeSound(): void;
}
// WRONG - does not implement makeSound()
class Dog extends Animal {
// Error: Missing implementation of abstract method 'makeSound'
}
// CORRECT - implements the abstract method
class Dog extends Animal {
makeSound(): void {
console.log("Woof!");
}
}Ensure your method declaration includes the return type. If the method returns void, explicitly state it. This makes your abstract contract clear to implementers.
abstract class Calculator {
// Good - return type is clear
abstract add(a: number, b: number): number;
abstract log(message: string): void;
// Bad - missing return type
abstract multiply(a, b);
}Make sure the parent class itself is marked with the abstract keyword. Without it, you cannot declare abstract methods at all.
// WRONG - class must be abstract
class Animal {
abstract makeSound(): void; // Error: only abstract classes can have abstract methods
}
// CORRECT - class is marked abstract
abstract class Animal {
abstract makeSound(): void;
}Most editors like VS Code offer a quick fix when you hover over the error. Click "Implement inherited abstract members" or similar to auto-generate method stubs in subclasses. This saves time and prevents mistakes.
After fixing the issue, run tsc --noEmit or npm run build to verify the error is gone. Make sure all subclasses properly implement abstract methods, and test your code to ensure it behaves as expected.
Abstract classes are a powerful tool for defining class hierarchies where you want to enforce a contract for subclasses while optionally providing shared implementation. A single abstract class can have both abstract methods (requiring subclass implementation) and concrete methods (providing default behavior). When using abstract classes with generic types, remember that abstract methods can also be generic: abstract process<T>(data: T): T;. If you are migrating from JavaScript to TypeScript, remember that JavaScript has no concept of abstract classes—this is purely a TypeScript compile-time feature. Abstract classes do not exist at runtime; they are stripped away during compilation. If you need to enforce method implementation at runtime in JavaScript, use regular class inheritance and throw errors for unimplemented methods.
Function expression requires a return type
Function expression requires a return type
Value of type 'string | undefined' is not iterable
How to fix "Value is not iterable" in TypeScript
Type 'undefined' is not assignable to type 'string'
How to fix "Type undefined is not assignable to type string" in TypeScript
Type narrowing from typeof check produces 'never'
How to fix "Type narrowing produces never" in TypeScript
Type parameter 'T' has conflicting constraints
How to fix "Type parameter has conflicting constraints" in TypeScript