fix(45345): throw an error on overridden member that is defined in multiple interfaces (#45352)
This commit is contained in:
parent
68eb1a551f
commit
ad894f74b3
|
@ -37687,8 +37687,8 @@ namespace ts {
|
|||
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);
|
||||
else if (prop && baseProp?.declarations && compilerOptions.noImplicitOverride && !nodeInAmbientContext) {
|
||||
const baseHasAbstract = some(baseProp.declarations, hasAbstractModifier);
|
||||
if (hasOverride) {
|
||||
return;
|
||||
}
|
||||
|
|
41
tests/baselines/reference/override20.errors.txt
Normal file
41
tests/baselines/reference/override20.errors.txt
Normal file
|
@ -0,0 +1,41 @@
|
|||
tests/cases/conformance/override/override20.ts(25,5): error TS4114: This member must have an 'override' modifier because it overrides a member in the base class 'I1 & I2'.
|
||||
tests/cases/conformance/override/override20.ts(28,5): error TS4114: This member must have an 'override' modifier because it overrides a member in the base class 'I1 & I2'.
|
||||
|
||||
|
||||
==== tests/cases/conformance/override/override20.ts (2 errors) ====
|
||||
const Foo: C1 & C2 =
|
||||
class {
|
||||
m1() { }
|
||||
m2() { }
|
||||
}
|
||||
|
||||
interface I1 {
|
||||
m1(): void;
|
||||
}
|
||||
|
||||
interface I2 {
|
||||
m1(): void;
|
||||
m2(): void;
|
||||
}
|
||||
|
||||
interface C1 {
|
||||
new(...args: any[]): I1;
|
||||
}
|
||||
|
||||
interface C2 {
|
||||
new(...args: any[]): I2;
|
||||
}
|
||||
|
||||
export class Bar extends Foo {
|
||||
m1() {
|
||||
~~
|
||||
!!! error TS4114: This member must have an 'override' modifier because it overrides a member in the base class 'I1 & I2'.
|
||||
super.m1();
|
||||
}
|
||||
m2() {
|
||||
~~
|
||||
!!! error TS4114: This member must have an 'override' modifier because it overrides a member in the base class 'I1 & I2'.
|
||||
super.m2();
|
||||
}
|
||||
}
|
||||
|
47
tests/baselines/reference/override20.js
Normal file
47
tests/baselines/reference/override20.js
Normal file
|
@ -0,0 +1,47 @@
|
|||
//// [override20.ts]
|
||||
const Foo: C1 & C2 =
|
||||
class {
|
||||
m1() { }
|
||||
m2() { }
|
||||
}
|
||||
|
||||
interface I1 {
|
||||
m1(): void;
|
||||
}
|
||||
|
||||
interface I2 {
|
||||
m1(): void;
|
||||
m2(): void;
|
||||
}
|
||||
|
||||
interface C1 {
|
||||
new(...args: any[]): I1;
|
||||
}
|
||||
|
||||
interface C2 {
|
||||
new(...args: any[]): I2;
|
||||
}
|
||||
|
||||
export class Bar extends Foo {
|
||||
m1() {
|
||||
super.m1();
|
||||
}
|
||||
m2() {
|
||||
super.m2();
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
//// [override20.js]
|
||||
const Foo = class {
|
||||
m1() { }
|
||||
m2() { }
|
||||
};
|
||||
export class Bar extends Foo {
|
||||
m1() {
|
||||
super.m1();
|
||||
}
|
||||
m2() {
|
||||
super.m2();
|
||||
}
|
||||
}
|
67
tests/baselines/reference/override20.symbols
Normal file
67
tests/baselines/reference/override20.symbols
Normal file
|
@ -0,0 +1,67 @@
|
|||
=== tests/cases/conformance/override/override20.ts ===
|
||||
const Foo: C1 & C2 =
|
||||
>Foo : Symbol(Foo, Decl(override20.ts, 0, 5))
|
||||
>C1 : Symbol(C1, Decl(override20.ts, 13, 1))
|
||||
>C2 : Symbol(C2, Decl(override20.ts, 17, 1))
|
||||
|
||||
class {
|
||||
m1() { }
|
||||
>m1 : Symbol(Foo.m1, Decl(override20.ts, 1, 11))
|
||||
|
||||
m2() { }
|
||||
>m2 : Symbol(Foo.m2, Decl(override20.ts, 2, 16))
|
||||
}
|
||||
|
||||
interface I1 {
|
||||
>I1 : Symbol(I1, Decl(override20.ts, 4, 5))
|
||||
|
||||
m1(): void;
|
||||
>m1 : Symbol(I1.m1, Decl(override20.ts, 6, 14))
|
||||
}
|
||||
|
||||
interface I2 {
|
||||
>I2 : Symbol(I2, Decl(override20.ts, 8, 1))
|
||||
|
||||
m1(): void;
|
||||
>m1 : Symbol(I2.m1, Decl(override20.ts, 10, 14))
|
||||
|
||||
m2(): void;
|
||||
>m2 : Symbol(I2.m2, Decl(override20.ts, 11, 15))
|
||||
}
|
||||
|
||||
interface C1 {
|
||||
>C1 : Symbol(C1, Decl(override20.ts, 13, 1))
|
||||
|
||||
new(...args: any[]): I1;
|
||||
>args : Symbol(args, Decl(override20.ts, 16, 8))
|
||||
>I1 : Symbol(I1, Decl(override20.ts, 4, 5))
|
||||
}
|
||||
|
||||
interface C2 {
|
||||
>C2 : Symbol(C2, Decl(override20.ts, 17, 1))
|
||||
|
||||
new(...args: any[]): I2;
|
||||
>args : Symbol(args, Decl(override20.ts, 20, 8))
|
||||
>I2 : Symbol(I2, Decl(override20.ts, 8, 1))
|
||||
}
|
||||
|
||||
export class Bar extends Foo {
|
||||
>Bar : Symbol(Bar, Decl(override20.ts, 21, 1))
|
||||
>Foo : Symbol(Foo, Decl(override20.ts, 0, 5))
|
||||
|
||||
m1() {
|
||||
>m1 : Symbol(Bar.m1, Decl(override20.ts, 23, 30))
|
||||
|
||||
super.m1();
|
||||
>super.m1 : Symbol(m1, Decl(override20.ts, 6, 14), Decl(override20.ts, 10, 14))
|
||||
>m1 : Symbol(m1, Decl(override20.ts, 6, 14), Decl(override20.ts, 10, 14))
|
||||
}
|
||||
m2() {
|
||||
>m2 : Symbol(Bar.m2, Decl(override20.ts, 26, 5))
|
||||
|
||||
super.m2();
|
||||
>super.m2 : Symbol(I2.m2, Decl(override20.ts, 11, 15))
|
||||
>m2 : Symbol(I2.m2, Decl(override20.ts, 11, 15))
|
||||
}
|
||||
}
|
||||
|
61
tests/baselines/reference/override20.types
Normal file
61
tests/baselines/reference/override20.types
Normal file
|
@ -0,0 +1,61 @@
|
|||
=== tests/cases/conformance/override/override20.ts ===
|
||||
const Foo: C1 & C2 =
|
||||
>Foo : C1 & C2
|
||||
|
||||
class {
|
||||
>class { m1() { } m2() { } } : typeof Foo
|
||||
|
||||
m1() { }
|
||||
>m1 : () => void
|
||||
|
||||
m2() { }
|
||||
>m2 : () => void
|
||||
}
|
||||
|
||||
interface I1 {
|
||||
m1(): void;
|
||||
>m1 : () => void
|
||||
}
|
||||
|
||||
interface I2 {
|
||||
m1(): void;
|
||||
>m1 : () => void
|
||||
|
||||
m2(): void;
|
||||
>m2 : () => void
|
||||
}
|
||||
|
||||
interface C1 {
|
||||
new(...args: any[]): I1;
|
||||
>args : any[]
|
||||
}
|
||||
|
||||
interface C2 {
|
||||
new(...args: any[]): I2;
|
||||
>args : any[]
|
||||
}
|
||||
|
||||
export class Bar extends Foo {
|
||||
>Bar : Bar
|
||||
>Foo : I1 & I2
|
||||
|
||||
m1() {
|
||||
>m1 : () => void
|
||||
|
||||
super.m1();
|
||||
>super.m1() : void
|
||||
>super.m1 : (() => void) & (() => void)
|
||||
>super : I1 & I2
|
||||
>m1 : (() => void) & (() => void)
|
||||
}
|
||||
m2() {
|
||||
>m2 : () => void
|
||||
|
||||
super.m2();
|
||||
>super.m2() : void
|
||||
>super.m2 : () => void
|
||||
>super : I1 & I2
|
||||
>m2 : () => void
|
||||
}
|
||||
}
|
||||
|
34
tests/cases/conformance/override/override20.ts
Normal file
34
tests/cases/conformance/override/override20.ts
Normal file
|
@ -0,0 +1,34 @@
|
|||
// @target: esnext
|
||||
// @noImplicitOverride: true
|
||||
|
||||
const Foo: C1 & C2 =
|
||||
class {
|
||||
m1() { }
|
||||
m2() { }
|
||||
}
|
||||
|
||||
interface I1 {
|
||||
m1(): void;
|
||||
}
|
||||
|
||||
interface I2 {
|
||||
m1(): void;
|
||||
m2(): void;
|
||||
}
|
||||
|
||||
interface C1 {
|
||||
new(...args: any[]): I1;
|
||||
}
|
||||
|
||||
interface C2 {
|
||||
new(...args: any[]): I2;
|
||||
}
|
||||
|
||||
export class Bar extends Foo {
|
||||
m1() {
|
||||
super.m1();
|
||||
}
|
||||
m2() {
|
||||
super.m2();
|
||||
}
|
||||
}
|
41
tests/cases/fourslash/codeFixOverrideModifier22.ts
Normal file
41
tests/cases/fourslash/codeFixOverrideModifier22.ts
Normal file
|
@ -0,0 +1,41 @@
|
|||
/// <reference path='fourslash.ts' />
|
||||
|
||||
// @noImplicitOverride: true
|
||||
|
||||
////const Foo: C1 & C2 =
|
||||
//// class {
|
||||
//// m1() { }
|
||||
//// m2() { }
|
||||
//// }
|
||||
////
|
||||
////interface I1 {
|
||||
//// m1(): void;
|
||||
////}
|
||||
////
|
||||
////interface I2 {
|
||||
//// m1(): void;
|
||||
//// m2(): void;
|
||||
////}
|
||||
////
|
||||
////interface C1 {
|
||||
//// new(...args: any[]): I1;
|
||||
////}
|
||||
////
|
||||
////interface C2 {
|
||||
//// new(...args: any[]): I2;
|
||||
////}
|
||||
////
|
||||
////class Bar extends Foo {
|
||||
//// [|m1()|] {
|
||||
//// super.m1();
|
||||
//// }
|
||||
//// m2() {
|
||||
//// super.m2();
|
||||
//// }
|
||||
////}
|
||||
|
||||
verify.codeFix({
|
||||
description: "Add 'override' modifier",
|
||||
newRangeContent: "override m1()",
|
||||
index: 0
|
||||
})
|
Loading…
Reference in a new issue