How to fix 'super' must be called before accessing properties on 'this' in a derived class in TypeScript

TypeScriptINTERMEDIATEMEDIUMUpdated Dec 11, 2025· 137 views

This TypeScript/JavaScript error occurs when you try to access properties or methods using "this" in a derived class constructor before calling the parent class constructor with super(). The parent class must be initialized first before the derived class can safely use its own properties.

Quick fix

Fixes 'super' must be called before accessing properties on 'this' in a derived class

// ❌ WRONG: Accessing "this" before super()
class Derived extends Base {
  constructor(value: string) {
    this.someProperty = value;  // Error: "this" before super()
    super();
  }
}

// ✅ CORRECT: Call super() first
class Derived extends Base {
  constructor(value: string) {
    super();  // Parent initialized first
    this.someProperty = value;  // Now safe to use "this"
  }
}
  1. Move super() call to the beginning of the constructor
  2. Pass arguments to super() if needed
  3. Fix property initializers that use "this"
  4. Handle parameter properties with "this" references
typescript — error
// ❌ WRONG: Accessing "this" before super()
class Derived extends Base {
constructor(value: string) {
this.someProperty = value; // Error: "this" before super()
super();
}
}
// ✅ CORRECT: Call super() first
class Derived extends Base {
constructor(value: string) {
super(); // Parent initialized first
this.someProperty = value; // Now safe to use "this"
}
}
'super' must be called before accessing properties on 'this' in a derived class

What this error means

The error "'super' must be called before accessing properties on 'this' in a derived class" is a fundamental JavaScript/TypeScript rule enforcement. In class-based inheritance, when you extend a parent class, the derived class's constructor must call super() before it can access the "this" keyword. This is because: 1. **Parent initialization first**: The parent class constructor needs to set up the instance first 2. **"this" is undefined**: Before super() is called, "this" doesn't refer to a valid object 3. **Inheritance chain**: Properties and methods from the parent class aren't available until after super() The error prevents runtime errors where you might try to access properties that haven't been initialized yet. This is especially important in TypeScript with strict class initialization checking enabled.

Typical symptoms

  • TypeScript compiler error: "super must be called before accessing this in derived class"
  • JavaScript runtime error in strict mode when accessing "this" before super()
  • Code fails to compile with TypeScript strict mode enabled
  • IDE shows red squiggly lines under "this" references before super() call
  • Class properties appear undefined when accessed before parent initialization

Common causes

  1. Accessing "this" keyword in derived class constructor before calling super()
  2. Trying to initialize derived class properties before parent class is ready
  3. Calling methods that use "this" before the parent constructor completes
  4. Using "this" in parameter default values or property initializers that run before super()
  5. Forgetting to call super() at the beginning of the derived constructor

How to fix "'super' must be called before accessing properties on 'this' in a derived class"

1Move super() call to the beginning of the constructor

The most common fix is to ensure super() is called before any "this" references:

typescript
// ❌ WRONG: Accessing "this" before super()
class Derived extends Base {
  constructor(value: string) {
    this.someProperty = value;  // Error: "this" before super()
    super();
  }
}

// ✅ CORRECT: Call super() first
class Derived extends Base {
  constructor(value: string) {
    super();  // Parent initialized first
    this.someProperty = value;  // Now safe to use "this"
  }
}

Always call super() as the first statement in your derived class constructor.

2Pass arguments to super() if needed

If the parent class constructor requires arguments, pass them to super():

typescript
// ❌ WRONG: Trying to process data before passing to parent
class User extends Person {
  constructor(name: string, age: number) {
    const processedName = name.trim();  // Error: "this" not available yet
    super(processedName, age);
  }
}

// ✅ CORRECT: Process arguments before constructor, or pass directly
class User extends Person {
  constructor(name: string, age: number) {
    // Process arguments before calling super()
    const processedName = name.trim();
    super(processedName, age);  // Parent gets processed values
  }
}

// ✅ ALTERNATIVE: Use a factory method if complex processing is needed
class User extends Person {
  private constructor(name: string, age: number) {
    super(name, age);
  }

  static create(name: string, age: number): User {
    const processedName = name.trim();
    return new User(processedName, age);
  }
}
3Fix property initializers that use "this"

Property initializers that reference "this" can cause this error:

typescript
// ❌ WRONG: Property initializer using "this" before super()
class Derived extends Base {
  private calculatedValue = this.computeValue();  // Error: "this" in initializer

  constructor() {
    super();
  }

  private computeValue(): number {
    return 42;
  }
}

// ✅ CORRECT: Initialize in constructor after super()
class Derived extends Base {
  private calculatedValue: number;

  constructor() {
    super();
    this.calculatedValue = this.computeValue();  // Safe after super()
  }

  private computeValue(): number {
    return 42;
  }
}

// ✅ ALTERNATIVE: Use a static method if no instance needed
class Derived extends Base {
  private calculatedValue = Derived.computeStaticValue();

  constructor() {
    super();
  }

  private static computeStaticValue(): number {
    return 42;
  }
}
4Handle parameter properties with "this" references

TypeScript parameter properties can't reference "this" before super():

typescript
// ❌ WRONG: Parameter property with "this" reference
class Derived extends Base {
  constructor(private value = this.getDefault()) {  // Error: "this" in default
    super();
  }

  private getDefault(): string {
    return 'default';
  }
}

// ✅ CORRECT: Handle default values differently
class Derived extends Base {
  private value: string;

  constructor(value?: string) {
    super();
    this.value = value ?? this.getDefault();  // Safe after super()
  }

  private getDefault(): string {
    return 'default';
  }
}

// ✅ ALTERNATIVE: Use undefined check with default parameter
class Derived extends Base {
  constructor(private value?: string) {
    super();
    if (this.value === undefined) {
      this.value = this.getDefault();
    }
  }

  private getDefault(): string {
    return 'default';
  }
}
5Check for "this" in arrow functions or methods called early

Methods or arrow functions that use "this" and are called before super() will fail:

typescript
// ❌ WRONG: Calling method that uses "this" before super()
class Derived extends Base {
  constructor() {
    this.initialize();  // Error: Method uses "this" internally
    super();
  }

  private initialize(): void {
    this.setup();  // Uses "this"
  }
}

// ✅ CORRECT: Call methods after super()
class Derived extends Base {
  constructor() {
    super();
    this.initialize();  // Safe after parent is initialized
  }

  private initialize(): void {
    this.setup();
  }
}

// ❌ WRONG: Arrow function in parameter default
class Derived extends Base {
  constructor(callback = () => this.doSomething()) {  // Error: "this" in arrow function
    super();
  }
}

// ✅ CORRECT: Handle callback initialization differently
class Derived extends Base {
  private callback: () => void;

  constructor(callback?: () => void) {
    super();
    this.callback = callback ?? (() => this.doSomething());  // Safe
  }
}
6Verify TypeScript compiler settings

Ensure your TypeScript configuration handles class initialization correctly:

json
// tsconfig.json
{
  "compilerOptions": {
    "strict": true,
    "strictPropertyInitialization": true,  // Catches uninitialized properties
    "noImplicitThis": true,  // Catches "this" with implicit 'any' type
    "target": "es2015"  // or higher for proper class support
  }
}

Key compiler options:
- strictPropertyInitialization: Ensures instance properties are initialized in constructor
- noImplicitThis: Error when "this" is implicitly 'any'
- useDefineForClassFields: Modern class field semantics (ES2022+)

Run tsc --noEmit to check for type errors after making changes.

Advanced notes

## Understanding JavaScript's Class Initialization Order

In JavaScript/TypeScript, class initialization follows this order:
1. Property initializers (ES2022 class fields) execute before the constructor
2. Constructor parameters are evaluated
3. super() must be called before accessing "this"
4. Remaining constructor body executes after super()

This is why property initializers can't use "this" - they run before the parent class is initialized.

## ES2022 Class Fields vs TypeScript's Implementation

TypeScript's class field behavior depends on the useDefineForClassFields compiler option:

- false (default for target < ES2022): Fields are initialized after super() in constructor
- true (ES2022+): Fields are initialized before constructor, following ES spec

With useDefineForClassFields: true, property initializers absolutely cannot use "this" since they run before the constructor.

## Abstract Classes and super()

For abstract classes, you still need to call super() even though there's no concrete parent:

typescript
abstract class Base {
  abstract initialize(): void;
}

class Derived extends Base {
  constructor() {
    super();  // Still required for abstract classes
    this.initialize();
  }

  initialize(): void {
    // implementation
  }
}

## Mixins and Multiple Inheritance Patterns

When using mixins or similar patterns, ensure each mixin's initialization happens in the correct order:

typescript
function Timestamped<T extends new (...args: any[]) => any>(Base: T) {
  return class extends Base {
    timestamp = Date.now();

    constructor(...args: any[]) {
      super(...args);  // Must call super() first
      // mixin initialization
    }
  };
}

## Performance Considerations

Calling super() early is not just a syntax requirement - it ensures proper memory layout and prototype chain setup. Accessing properties before the parent is initialized can lead to memory corruption or incorrect property lookups in optimized JavaScript engines.

Frequently asked questions

What does "'super' must be called before accessing properties on 'this' in a deri" mean?
The error "'super' must be called before accessing properties on 'this' in a derived class" is a fundamental JavaScript/TypeScript rule enforcement. In class-based inheritance, when you extend a parent class, the derived class's constructor must call super() before it can access the "this" keyword. This is because: 1.
How do I fix "'super' must be called before accessing properties on 'this' in a deri"?
This TypeScript/JavaScript error occurs when you try to access properties or methods using "this" in a derived class constructor before calling the parent class constructor with super(). The parent class must be initialized first before the derived class can safely use its own properties.
What causes "'super' must be called before accessing properties on 'this' in a deri"?
Accessing "this" keyword in derived class constructor before calling super() Trying to initialize derived class properties before parent class is ready Calling methods that use "this" before the parent constructor completes
Is the "'super' must be called before accessing properties on 'this' in a deri" error serious?
It is a medium-severity error — more of a blocker than a risk. The steps above resolve it.

Official resources & further reading