TypeScript error

TS2416: A subclass member that does not fit the base class

  • Error TS2416
  • Tested with TypeScript 5.9

A subclass can be used anywhere its base class is expected, so each member it overrides has to fit the base member's type: a method returning a number cannot be overridden by one returning a string. TS2416 names the member and both types, and the lines under it say what differs.

In a .js file the subclass's types come from its JSDoc and from inference, so an override with no annotations is checked against the base class through what its body returns.

At a glance

CodeTS2416
MessageProperty '{0}' in type '{1}' is not assignable to the same property in base type '{2}'.
TypeScript's categoryerror
Listed underClasses, JSX and unused code
Turned on by No option: every checked file reports it
In .js files Reported when the file is checked: checkJs in jsconfig.json, or // @ts-check at the top of the file

The message is TypeScript's own text from its diagnostic messages file (Apache-2.0); {0}, {1} and {2} are filled in by tsc for each error.

What it looks like

shapes.js Error confirmed 5.9.3 TypeScript 5.9.3, run 21 October 2026: shapes.js(16,3): error TS2416: Property 'area' in type 'Square' is not assignable to the same property in base type 'Shape'. Type '() => string' is not assignable to type '() => number'. Type 'string' is not assignable to type 'number'. 6.0.3 TypeScript 6.0.3, run 21 October 2026: the same as 5.9.3. shapes.js(16,3): error TS2416: Property 'area' in type 'Square' is not assignable to the same property in base type 'Shape'. Type '() => string' is not assignable to type '() => number'. Type 'string' is not assignable to type 'number'. 7.0.2 TypeScript 7.0.2, run 21 October 2026: the same as 5.9.3. shapes.js(16,3): error TS2416: Property 'area' in type 'Square' is not assignable to the same property in base type 'Shape'. Type '() => string' is not assignable to type '() => number'. Type 'string' is not assignable to type 'number'. checked 21 October 2026
class Shape {
  /** @returns {number} */
  area() {
    return 0;
  }
}

export class Square extends Shape {
  /** @param {number} side */
  constructor(side) {
    super();
    this.side = side;
  }

  area() {error TS2416: Property 'area' in type 'Square' is not assignable to the same property in base type 'Shape'.
  Type '() => string' is not assignable to type '() => number'.
    Type 'string' is not assignable to type 'number'.
    return `${this.side ** 2} square meters`;
  }
}
A subclass method that returns a different type than the base.
jsconfig.json for this example
{
  "compilerOptions": {
    "checkJs": true,
    "noEmit": true,
    "strict": true,
    "target": "es2022",
    "module": "nodenext",
    "types": []
  },
  "include": ["**/*.js"]
}

What causes it

  • An override returns a different type, as in the example.
  • An override takes a narrower parameter type than the base method accepts.
  • A class claims to implement an interface with @implements and a method's parameter type does not fit.

How to fix it

Make the override compatible

Return the base type (here a number) and put the formatting in a new method. If the base class's type is what is wrong, change it there.

shapes.js TypeScript 5.9.3 TypeScript 5.9.3, run 21 October 2026: No errors. 6.0.3 TypeScript 6.0.3, run 21 October 2026: the same as 5.9.3. No errors. 7.0.2 TypeScript 7.0.2, run 21 October 2026: the same as 5.9.3. No errors. checked 21 October 2026
class Shape {
  /** @returns {number} */
  area() {
    return 0;
  }
}

export class Square extends Shape {
  /** @param {number} side */
  constructor(side) {
    super();
    this.side = side;
  }

  area() {
    return this.side ** 2;
  }

  label() {
    return `${this.area()} square meters`;
  }
}
The override returns what the base promises.
jsconfig.json for this example
{
  "compilerOptions": {
    "checkJs": true,
    "noEmit": true,
    "strict": true,
    "target": "es2022",
    "module": "nodenext",
    "types": []
  },
  "include": ["**/*.js"]
}

Gotchas

  • Parameters are compared both ways for methods written as methods (TypeScript's method bivariance), so a narrower parameter in a method override is often accepted; property-style function types are checked strictly under strictFunctionTypes.

Sources

Last reviewed 21 October 2026.