diff --git a/src/compiler/checker.ts b/src/compiler/checker.ts index 3fbc4cd158b..26bd2a70d27 100644 --- a/src/compiler/checker.ts +++ b/src/compiler/checker.ts @@ -37308,7 +37308,10 @@ namespace ts { const baseClassName = typeToString(baseWithThis); if (prop && !baseProp && hasOverride) { - error(member, Diagnostics.This_member_cannot_have_an_override_modifier_because_it_is_not_declared_in_the_base_class_0, baseClassName); + const suggestion = getSpellingSuggestionForName(symbolName(declaredProp), arrayFrom(getMembersOfSymbol(baseType.symbol).values()), SymbolFlags.ClassMember); + suggestion ? + error(member, Diagnostics.This_member_cannot_have_an_override_modifier_because_it_is_not_declared_in_the_base_class_0_Did_you_mean_1, baseClassName, symbolToString(suggestion)) : + error(member, Diagnostics.This_member_cannot_have_an_override_modifier_because_it_is_not_declared_in_the_base_class_0, baseClassName); } else if (prop && baseProp?.valueDeclaration && compilerOptions.noImplicitOverride && !nodeInAmbientContext) { const baseHasAbstract = hasAbstractModifier(baseProp.valueDeclaration); diff --git a/src/compiler/diagnosticMessages.json b/src/compiler/diagnosticMessages.json index 0c766fbde12..e8d52eadb61 100644 --- a/src/compiler/diagnosticMessages.json +++ b/src/compiler/diagnosticMessages.json @@ -3733,6 +3733,10 @@ "category": "Error", "code": 4116 }, + "This member cannot have an 'override' modifier because it is not declared in the base class '{0}'. Did you mean '{1}'?": { + "category": "Error", + "code": 4117 + }, "The current host does not support the '{0}' option.": { "category": "Error", diff --git a/tests/baselines/reference/override15.errors.txt b/tests/baselines/reference/override15.errors.txt new file mode 100644 index 00000000000..46444eef697 --- /dev/null +++ b/tests/baselines/reference/override15.errors.txt @@ -0,0 +1,14 @@ +tests/cases/conformance/override/override15.ts(6,14): error TS4117: This member cannot have an 'override' modifier because it is not declared in the base class 'A'. Did you mean 'doSomething'? + + +==== tests/cases/conformance/override/override15.ts (1 errors) ==== + class A { + doSomething() {} + } + + class B extends A { + override doSomethang() {} + ~~~~~~~~~~~ +!!! error TS4117: This member cannot have an 'override' modifier because it is not declared in the base class 'A'. Did you mean 'doSomething'? + } + \ No newline at end of file diff --git a/tests/baselines/reference/override15.js b/tests/baselines/reference/override15.js new file mode 100644 index 00000000000..8ead6675121 --- /dev/null +++ b/tests/baselines/reference/override15.js @@ -0,0 +1,40 @@ +//// [override15.ts] +class A { + doSomething() {} +} + +class B extends A { + override doSomethang() {} +} + + +//// [override15.js] +var __extends = (this && this.__extends) || (function () { + var extendStatics = function (d, b) { + extendStatics = Object.setPrototypeOf || + ({ __proto__: [] } instanceof Array && function (d, b) { d.__proto__ = b; }) || + function (d, b) { for (var p in b) if (Object.prototype.hasOwnProperty.call(b, p)) d[p] = b[p]; }; + return extendStatics(d, b); + }; + return function (d, b) { + if (typeof b !== "function" && b !== null) + throw new TypeError("Class extends value " + String(b) + " is not a constructor or null"); + extendStatics(d, b); + function __() { this.constructor = d; } + d.prototype = b === null ? Object.create(b) : (__.prototype = b.prototype, new __()); + }; +})(); +var A = /** @class */ (function () { + function A() { + } + A.prototype.doSomething = function () { }; + return A; +}()); +var B = /** @class */ (function (_super) { + __extends(B, _super); + function B() { + return _super !== null && _super.apply(this, arguments) || this; + } + B.prototype.doSomethang = function () { }; + return B; +}(A)); diff --git a/tests/baselines/reference/override15.symbols b/tests/baselines/reference/override15.symbols new file mode 100644 index 00000000000..0c9f6acef6b --- /dev/null +++ b/tests/baselines/reference/override15.symbols @@ -0,0 +1,16 @@ +=== tests/cases/conformance/override/override15.ts === +class A { +>A : Symbol(A, Decl(override15.ts, 0, 0)) + + doSomething() {} +>doSomething : Symbol(A.doSomething, Decl(override15.ts, 0, 9)) +} + +class B extends A { +>B : Symbol(B, Decl(override15.ts, 2, 1)) +>A : Symbol(A, Decl(override15.ts, 0, 0)) + + override doSomethang() {} +>doSomethang : Symbol(B.doSomethang, Decl(override15.ts, 4, 19)) +} + diff --git a/tests/baselines/reference/override15.types b/tests/baselines/reference/override15.types new file mode 100644 index 00000000000..8b8e67a52c9 --- /dev/null +++ b/tests/baselines/reference/override15.types @@ -0,0 +1,16 @@ +=== tests/cases/conformance/override/override15.ts === +class A { +>A : A + + doSomething() {} +>doSomething : () => void +} + +class B extends A { +>B : B +>A : A + + override doSomethang() {} +>doSomethang : () => void +} + diff --git a/tests/cases/conformance/override/override15.ts b/tests/cases/conformance/override/override15.ts new file mode 100644 index 00000000000..882cc7eb97a --- /dev/null +++ b/tests/cases/conformance/override/override15.ts @@ -0,0 +1,9 @@ +// @noImplicitOverride: true + +class A { + doSomething() {} +} + +class B extends A { + override doSomethang() {} +}