Fixing the 'super' Before 'this' Error in TypeScript

intermediate๐Ÿ”ต TypeScript2026-07-12| TypeScript 2.0+, Node.js, VS Code, WebStorm.

Error Message

'super' must be called before accessing 'this' in the constructor of a derived class.
#typescript#inheritance#oop#javascript#web-development

The Constructor Catch-22

Your build fails. The terminal spits out a cryptic message about super and this. You were just trying to refactor a core service, but now your IDE is covered in red squiggles. This error is a classic rite of passage for TypeScript developers.

'super' must be called before accessing 'this' in the constructor of a derived class.

Modern JavaScript and TypeScript follow a strict inheritance protocol. The parent class must exist before the child class can modify it. If you try to touch this before calling super(), the engine blocks you because the instance hasn't actually been initialized yet. You are essentially trying to paint a room in a house that hasn't been framed.

A Real-World Failure

Suppose you are building a DatabaseService. You want to extend a base class to handle specific user logic, but you try to set a property too early:

class BaseService {
  protected apiVersion: number;
  constructor(version: number) {
    this.apiVersion = version;
  }
}

class UserService extends BaseService {
  private endpoint: string;

  constructor(version: number) {
    // โŒ Error: this.endpoint accessed before super()
    this.endpoint = '/users'; 
    super(version);
  }
}

That this.endpoint assignment triggers the error. TypeScript sees you interacting with the UserService instance before the BaseService has had a chance to set up its own internal state.

Why the Engine Blocks You

In ES6 classes, the this keyword is not magically available the moment the constructor starts. Instead, the super() call is what binds this to the current instance. Until that function finishes, this remains uninitialized.

Allowing access to this before super() would be dangerous. You might call a method that relies on a parent property which is currently undefined. This restriction prevents a whole category of runtime crashes that used to plague older JavaScript patterns.

The 30-Second Fix: Reordering

Most of the time, the solution is trivial. Move super() to the very top of your constructor. This ensures the foundation is solid before you start decorating.

class UserService extends BaseService {
  private endpoint: string;

  constructor(version: number) {
    super(version); // โœ… Foundation laid
    
    this.endpoint = '/users'; // โœ… Safe to use 'this'
  }
}

Managing Logic Before the Super Call

What if you need to calculate a value to pass into the super() call? You can't use this to do it, but you aren't stuck.

The Wrong Way

constructor(config: any) {
  this.token = this.decrypt(config.key); // Error: this.decrypt is not available yet
  super(this.token);
}

The Right Way: Local Variables and Static Methods

Use local variables or static helper functions. These exist on the class itself, not the instance, so they don't require this to function.

class UserService extends BaseService {
  constructor(config: any) {
    // 1. Perform logic using local constants
    const decryptedToken = UserService.decrypt(config.key);
    
    // 2. Pass the result to the parent
    super(decryptedToken);
    
    // 3. Complete instance setup
    console.log("User service active.");
  }

  private static decrypt(key: string): string {
    return key.split('').reverse().join(''); // Simplified logic
  }
}

Verification and Testing

Don't just trust the lack of red lines. Verify your fix with these three steps:

  • Run the Compiler: Hit npx tsc. If it returns no errors, your inheritance chain is syntactically sound.
  • Check Runtime Errors: If you see ReferenceError: Must call super constructor... in your browser console, you likely have a hidden this access in a property initializer.
  • Unit Test Initialization: Create a test case that instantiates the class. Confirm that both parent and child properties (e.g., this.apiVersion and this.endpoint) are exactly what you expect.

Sticking to the "super first" rule keeps your object-oriented code predictable. Use static helpers for pre-initialization logic and you'll never see this error again.

Related Error Notes