This error occurs when a derived class fails to implement all abstract properties declared in its abstract base class. TypeScript requires that any class extending an abstract class must provide concrete implementations for every abstract member. Fixing this involves adding the missing property implementations to your derived class.
In TypeScript, an abstract class can declare abstract properties that do not have an implementation. These serve as a contract that all classes inheriting from the abstract class must fulfill. When you create a derived class that extends an abstract class, you must provide implementations for all abstract properties. If you forget to implement even one abstract property, TypeScript will raise a compile-time error. This error prevents you from instantiating the derived class or running your code, forcing you to honor the contract defined by the abstract base class. The error message will specify which abstract property is missing an implementation and which class is responsible for implementing it.
Check the error message to see which property name is not implemented. Look at the abstract class definition to find all abstract properties (they are prefixed with the abstract keyword). Compare the list to what you have in the derived class.
// Abstract base class
abstract class Animal {
abstract name: string; // Abstract property
abstract age: number; // Abstract property
abstract makeSound(): void; // Abstract method
}
// WRONG - missing properties
class Dog extends Animal {
makeSound() {
console.log("Woof");
}
// ERROR: 'name' and 'age' not implemented
}For each abstract property, declare it in the derived class with the same type. You can initialize it directly as a class property, or initialize it in the constructor. The type must match the abstract declaration.
class Dog extends Animal {
name: string;
age: number;
constructor(name: string, age: number) {
this.name = name;
this.age = age;
}
makeSound() {
console.log("Woof");
}
}
// Now this works
const dog = new Dog("Buddy", 3);The most common approach is to initialize abstract properties in the constructor. This allows instances to have different values for the properties. Remember to call super() if the abstract class has a constructor.
abstract class Vehicle {
abstract brand: string;
abstract wheels: number;
abstract drive(): void;
}
class Car extends Vehicle {
brand: string;
wheels: number = 4; // Can set default
constructor(brand: string) {
super();
this.brand = brand;
}
drive() {
console.log(`${this.brand} car is driving`);
}
}
const myCar = new Car("Toyota");
console.log(myCar.wheels); // 4The property in the derived class must have the same type as the abstract declaration. If the abstract property is readonly, the derived property should also be readonly. The access modifier (public, protected, private) must be compatible.
abstract class BaseClass {
abstract readonly id: string;
abstract status: "active" | "inactive";
}
class DerivedClass extends BaseClass {
readonly id: string; // Must match: readonly and string type
status: "active" | "inactive"; // Must match: same union type
constructor(id: string) {
this.id = id;
this.status = "active";
}
}If the abstract class defines an abstract property with getters/setters, implement the same pattern in the derived class. Use get and set accessors to wrap the property.
abstract class User {
abstract name: string;
abstract get email(): string;
abstract set email(value: string);
}
class Customer extends User {
name: string;
private _email: string;
constructor(name: string, email: string) {
this.name = name;
this._email = email;
}
get email(): string {
return this._email;
}
set email(value: string) {
this._email = value;
}
}After implementing all abstract properties, try to create an instance of the derived class. If the implementation is correct, this should work without errors. If you still get errors, check that all abstract properties from all levels of inheritance are implemented.
// Test that the implementation works
const dog = new Dog("Max", 2);
console.log(dog.name); // "Max"
console.log(dog.age); // 2
console.log(dog.makeSound()); // "Woof"
// TypeScript now confirms all abstract properties are satisfiedIf you have a chain of inheritance (abstract class A → abstract class B → concrete class C), make sure you implement all abstract properties from both A and B. Sometimes the error is in an intermediate class that also needs to implement properties.
abstract class Base {
abstract id: string;
}
abstract class Middle extends Base {
abstract name: string;
}
class Concrete extends Middle {
id: string = "1"; // From Base
name: string = "Test"; // From Middle
// Now both are implemented
}Abstract properties are a form of interface enforcement at the class level. Unlike interfaces, abstract classes can have implementations for some methods and properties while enforcing contracts on others. This provides more flexibility for shared behavior. When debugging missing abstract property errors, note that TypeScript performs strict checking at compile time, so all abstract members must be satisfied before the code runs. You can view the compiled JavaScript to see that abstract keywords are removed—they exist only for type checking. If you have a complex inheritance hierarchy, consider using interfaces alongside abstract classes for clearer contracts. Some developers prefer interfaces for pure contracts and abstract classes for shared implementations, though TypeScript allows both approaches.
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