How to fix Class 'UserService' does not implement interface 'IUserService' in TypeScript

TypeScriptBEGINNERMEDIUMUpdated Dec 8, 2025· 119 views

This error occurs when a class declares that it implements an interface but is missing one or more required properties or methods. The fix involves adding all missing members or marking interface members as optional.

Quick fix

Fixes TS2420

Class 'UserService' does not implement interface 'IUserService'.
  Property 'getName' is missing in type 'UserService' but required in type 'IUserService'.
  1. Read the TypeScript error message carefully
  2. Review your interface definition
  3. Add all missing properties and methods to your class
  4. Check method signatures match the interface
typescript — error
Class 'UserService' does not implement interface 'IUserService'.
Property 'getName' is missing in type 'UserService' but required in type 'IUserService'.
Class 'UserService' does not implement interface 'IUserService'

What this error means

When you use the `implements` keyword in TypeScript, you're telling the compiler that your class must satisfy the interface contract—meaning it must define all properties and methods that the interface specifies. If your class is missing any of these required members, or if a member has an incompatible type, TypeScript raises the error "Class does not implement interface". This is a compile-time safety feature that prevents mismatches between what code expects and what your class actually provides. This is one of the most common TypeScript errors because it's easy to forget to implement all interface members, especially in interfaces with many properties or when inheriting from interfaces that extend other interfaces.

Typical symptoms

  • TypeScript compiler shows TS2420 error on class declaration
  • Error message specifies which property or method is missing
  • IDE highlights the class name with a red squiggle
  • Build fails with compilation error before code runs
  • Error appears immediately after adding `implements InterfaceName` to a class

Common causes

  1. Class is missing one or more required properties defined in the interface (most common)
  2. Property exists but has an incompatible type (e.g., string instead of number)
  3. Method signature doesn't match interface (wrong parameters or return type)
  4. Property is marked as optional in the class (?) but required in interface, or vice versa
  5. Class doesn't implement all methods in a multi-interface inheritance chain
  6. Method is declared as private in the class but public in the interface

How to fix "Class 'UserService' does not implement interface 'IUserService'"

1Read the TypeScript error message carefully

The error message tells you exactly what's missing. For example:

bash
Class 'UserService' does not implement interface 'IUserService'.
  Property 'getName' is missing in type 'UserService' but required in type 'IUserService'.

This tells you that:
1. Your class is named UserService
2. It's trying to implement IUserService
3. The getName property/method is missing

Note the exact name and type of the missing member.

2Review your interface definition

Open the interface definition and identify all required members:

typescript
interface IUserService {
  getName(): string;           // Method that returns string
  getUserId(): number;         // Method that returns number
  email: string;               // Property
  isActive?: boolean;          // Optional property
}

Pay attention to:
- Method names and their return types
- Property names and types
- Which members are optional (?)

3Add all missing properties and methods to your class

Implement every required member from the interface:

typescript
class UserService implements IUserService {
  email: string = "";

  constructor() {
    this.email = "user@example.com";
  }

  getName(): string {
    return "John Doe";
  }

  getUserId(): number {
    return 42;
  }

  // isActive is optional, so you don't have to implement it
}

Make sure:
- Method names match exactly
- Return types match (string returns string, number returns number, etc.)
- Properties have the correct types

4Check method signatures match the interface

Ensure method parameters and return types are correct:

typescript
// ❌ WRONG - wrong return type
interface IService {
  getValue(): string;
}

class Service implements IService {
  getValue(): number {  // ERROR: number is not string
    return 42;
  }
}

// ✅ CORRECT - matching signature
class Service implements IService {
  getValue(): string {
    return "42";
  }
}

Parameters must also match:

typescript
// ❌ WRONG - missing parameter
interface ILogger {
  log(message: string, level: "info" | "error"): void;
}

class Logger implements ILogger {
  log(message: string): void {  // ERROR: missing level parameter
    console.log(message);
  }
}

// ✅ CORRECT
class Logger implements ILogger {
  log(message: string, level: "info" | "error"): void {
    console.log(`[${level}] ${message}`);
  }
}
5Verify access modifiers match

Properties and methods must have compatible access levels:

typescript
// ❌ WRONG - interface member is public but class member is private
interface IService {
  getData(): string;  // implicitly public
}

class Service implements IService {
  private getData(): string {  // ERROR: private doesn't match public
    return "data";
  }
}

// ✅ CORRECT - both public
class Service implements IService {
  public getData(): string {  // or just: getData(): string
    return "data";
  }
}

Note: You can't make a class member more restrictive (private/protected) than the interface declares it.

6Use optional members if not all methods are needed

If you don't need to implement every member, mark them as optional in the interface:

typescript
interface IService {
  name: string;
  getValue(): number;
  cache?: Map<string, any>;  // Optional property
  reset?(): void;             // Optional method
}

class MinimalService implements IService {
  name = "Service";
  getValue() {
    return 42;
  }
  // cache and reset are optional, so they don't need to be implemented
}

However, it's usually better to create separate, smaller interfaces for different use cases rather than having large interfaces with many optional members.

7Check for multi-interface inheritance chains

When a class implements multiple interfaces or when interfaces extend other interfaces, make sure you implement everything:

typescript
interface IBase {
  id: number;
}

interface IExtended extends IBase {
  name: string;
}

// ❌ WRONG - missing id (from IBase)
class Model implements IExtended {
  name: string = "";
}

// ✅ CORRECT - implements all members from the chain
class Model implements IExtended {
  id: number = 0;
  name: string = "";
}

Alternatively, a class can implement both explicitly:

typescript
// ✅ Also correct
class Model implements IBase, IExtended {
  id: number = 0;
  name: string = "";
}

Advanced notes

### Using Satisfies Operator (TypeScript 4.9+)

The satisfies operator can help catch interface mismatches without explicitly declaring implements:

typescript
const service = {
  getName: () => "John",
  getValue: () => 42,
} satisfies IService;

This checks the object against the interface without the overhead of creating a class.

### Structural vs Nominal Typing

TypeScript uses "structural typing"—it checks that an object has the right shape, not just that it declares implements. An object can satisfy an interface without explicitly declaring it:

typescript
interface Duck {
  quack(): void;
  swim(): void;
}

const mallard = {
  quack() { console.log("quack!"); },
  swim() { console.log("swimming!"); },
};

// mallard satisfies Duck structurally, even without "implements"

However, using explicit implements gives you better IDE support and earlier error detection.

### Narrowing Interface Implementations

For large interfaces, consider splitting into smaller, focused interfaces:

typescript
// ❌ Large interface with many unrelated methods
interface IUserService {
  getUser(): User;
  updateUser(user: User): void;
  deleteUser(id: string): void;
  sendEmail(to: string, message: string): void;
  logActivity(action: string): void;
}

// ✅ Better: separate concerns
interface IUserRepository {
  getUser(): User;
  updateUser(user: User): void;
  deleteUser(id: string): void;
}

interface INotificationService {
  sendEmail(to: string, message: string): void;
}

interface IAuditService {
  logActivity(action: string): void;
}

class UserService implements IUserRepository, INotificationService, IAuditService {
  // Clearer what each method is responsible for
}

This makes it easier to implement interfaces and follow the Single Responsibility Principle.

### Abstract Classes vs Interfaces

Abstract classes are similar but allow implementation:

typescript
abstract class BaseService {
  abstract getData(): string;  // Must be implemented by subclass

  processData() {              // Can have default implementation
    const data = this.getData();
    return data.toUpperCase();
  }
}

class Service extends BaseService {
  getData() {
    return "hello";
  }
}

Abstract classes are useful when you want to share implementation code, while interfaces are purely structural contracts.

Frequently asked questions

What does "TS2420" mean?
When you use the implements keyword in TypeScript, you're telling the compiler that your class must satisfy the interface contract—meaning it must define all properties and methods that the interface specifies. If your class is missing any of these required members, or if a member has an incompatible type, TypeScript raises the error "Class does not implement interface". This is a compile-time safety feature that prevents mismatches between what code expects and what your class actually provides.
How do I fix "TS2420"?
This error occurs when a class declares that it implements an interface but is missing one or more required properties or methods. The fix involves adding all missing members or marking interface members as optional.
What causes "TS2420"?
Class is missing one or more required properties defined in the interface (most common) Property exists but has an incompatible type (e.g., string instead of number) Method signature doesn't match interface (wrong parameters or return type)
Is the "TS2420" error serious?
It is a medium-severity error — more of a blocker than a risk. The steps above resolve it.

Official resources & further reading