Skip to content

Commit 6baa1be

Browse files
Orta Theroxaustincummings
Orta Therox
andauthored
Improve non-ambient class and function merge error (#44352)
* Improve non-ambient class and function merge error * Update baselines * Update tests Co-authored-by: Austin Cummings <[email protected]>
1 parent 9d345e7 commit 6baa1be

19 files changed

+167
-160
lines changed

src/compiler/checker.ts

+15-6
Original file line numberDiff line numberDiff line change
@@ -34057,13 +34057,22 @@ namespace ts {
3405734057
});
3405834058
}
3405934059

34060-
if (hasNonAmbientClass && !isConstructor && symbol.flags & SymbolFlags.Function) {
34061-
// A non-ambient class cannot be an implementation for a non-constructor function/class merge
34062-
// TODO: The below just replicates our older error from when classes and functions were
34063-
// entirely unable to merge - a more helpful message like "Class declaration cannot implement overload list"
34064-
// might be warranted. :shrug:
34060+
if (hasNonAmbientClass && !isConstructor && symbol.flags & SymbolFlags.Function && declarations) {
34061+
const relatedDiagnostics = filter(declarations, d => d.kind === SyntaxKind.ClassDeclaration)
34062+
.map(d => createDiagnosticForNode(d, Diagnostics.Consider_adding_a_declare_modifier_to_this_class));
34063+
3406534064
forEach(declarations, declaration => {
34066-
addDuplicateDeclarationError(declaration, Diagnostics.Duplicate_identifier_0, symbolName(symbol), declarations);
34065+
const diagnostic = declaration.kind === SyntaxKind.ClassDeclaration
34066+
? Diagnostics.Class_declaration_cannot_implement_overload_list_for_0
34067+
: declaration.kind === SyntaxKind.FunctionDeclaration
34068+
? Diagnostics.Function_with_bodies_can_only_merge_with_classes_that_are_ambient
34069+
: undefined;
34070+
if (diagnostic) {
34071+
addRelatedInfo(
34072+
error(getNameOfDeclaration(declaration) || declaration, diagnostic, symbolName(symbol)),
34073+
...relatedDiagnostics
34074+
);
34075+
}
3406734076
});
3406834077
}
3406934078

src/compiler/diagnosticMessages.json

+14-1
Original file line numberDiff line numberDiff line change
@@ -3336,6 +3336,14 @@
33363336
"category": "Error",
33373337
"code": 2812
33383338
},
3339+
"Class declaration cannot implement overload list for '{0}'.": {
3340+
"category": "Error",
3341+
"code": 2813
3342+
},
3343+
"Function with bodies can only merge with classes that are ambient.": {
3344+
"category": "Error",
3345+
"code": 2814
3346+
},
33393347

33403348
"Import declaration '{0}' is using private name '{1}'.": {
33413349
"category": "Error",
@@ -5172,6 +5180,11 @@
51725180
"category": "Message",
51735181
"code": 6505
51745182
},
5183+
"Consider adding a 'declare' modifier to this class.": {
5184+
"category": "Message",
5185+
"code": 6506
5186+
},
5187+
51755188

51765189
"Include 'undefined' in index signature results": {
51775190
"category": "Message",
@@ -5185,7 +5198,7 @@
51855198
"category": "Message",
51865199
"code": 6802
51875200
},
5188-
5201+
51895202
"Variable '{0}' implicitly has an '{1}' type.": {
51905203
"category": "Error",
51915204
"code": 7005
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,7 @@
11
tests/cases/compiler/augmentedTypesClass2a.ts(2,7): error TS2300: Duplicate identifier 'c2'.
2-
tests/cases/compiler/augmentedTypesClass2a.ts(2,7): error TS2300: Duplicate identifier 'c2'.
3-
tests/cases/compiler/augmentedTypesClass2a.ts(3,10): error TS2300: Duplicate identifier 'c2'.
2+
tests/cases/compiler/augmentedTypesClass2a.ts(2,7): error TS2813: Class declaration cannot implement overload list for 'c2'.
43
tests/cases/compiler/augmentedTypesClass2a.ts(3,10): error TS2300: Duplicate identifier 'c2'.
4+
tests/cases/compiler/augmentedTypesClass2a.ts(3,10): error TS2814: Function with bodies can only merge with classes that are ambient.
55
tests/cases/compiler/augmentedTypesClass2a.ts(4,5): error TS2300: Duplicate identifier 'c2'.
66

77

@@ -10,15 +10,15 @@ tests/cases/compiler/augmentedTypesClass2a.ts(4,5): error TS2300: Duplicate iden
1010
class c2 { public foo() { } } // error
1111
~~
1212
!!! error TS2300: Duplicate identifier 'c2'.
13-
!!! related TS6203 tests/cases/compiler/augmentedTypesClass2a.ts:3:10: 'c2' was also declared here.
1413
~~
15-
!!! error TS2300: Duplicate identifier 'c2'.
14+
!!! error TS2813: Class declaration cannot implement overload list for 'c2'.
15+
!!! related TS6506 tests/cases/compiler/augmentedTypesClass2a.ts:2:7: Consider adding a 'declare' modifier to this class.
1616
function c2() { } // error
1717
~~
1818
!!! error TS2300: Duplicate identifier 'c2'.
19-
!!! related TS6203 tests/cases/compiler/augmentedTypesClass2a.ts:2:7: 'c2' was also declared here.
2019
~~
21-
!!! error TS2300: Duplicate identifier 'c2'.
20+
!!! error TS2814: Function with bodies can only merge with classes that are ambient.
21+
!!! related TS6506 tests/cases/compiler/augmentedTypesClass2a.ts:2:7: Consider adding a 'declare' modifier to this class.
2222
var c2 = () => { }
2323
~~
2424
!!! error TS2300: Duplicate identifier 'c2'.

tests/baselines/reference/augmentedTypesFunction.errors.txt

+12-12
Original file line numberDiff line numberDiff line change
@@ -4,10 +4,10 @@ tests/cases/compiler/augmentedTypesFunction.ts(6,10): error TS2393: Duplicate fu
44
tests/cases/compiler/augmentedTypesFunction.ts(7,10): error TS2393: Duplicate function implementation.
55
tests/cases/compiler/augmentedTypesFunction.ts(9,10): error TS2300: Duplicate identifier 'y2a'.
66
tests/cases/compiler/augmentedTypesFunction.ts(10,5): error TS2300: Duplicate identifier 'y2a'.
7-
tests/cases/compiler/augmentedTypesFunction.ts(13,10): error TS2300: Duplicate identifier 'y3'.
8-
tests/cases/compiler/augmentedTypesFunction.ts(14,7): error TS2300: Duplicate identifier 'y3'.
9-
tests/cases/compiler/augmentedTypesFunction.ts(16,10): error TS2300: Duplicate identifier 'y3a'.
10-
tests/cases/compiler/augmentedTypesFunction.ts(17,7): error TS2300: Duplicate identifier 'y3a'.
7+
tests/cases/compiler/augmentedTypesFunction.ts(13,10): error TS2814: Function with bodies can only merge with classes that are ambient.
8+
tests/cases/compiler/augmentedTypesFunction.ts(14,7): error TS2813: Class declaration cannot implement overload list for 'y3'.
9+
tests/cases/compiler/augmentedTypesFunction.ts(16,10): error TS2814: Function with bodies can only merge with classes that are ambient.
10+
tests/cases/compiler/augmentedTypesFunction.ts(17,7): error TS2813: Class declaration cannot implement overload list for 'y3a'.
1111
tests/cases/compiler/augmentedTypesFunction.ts(20,10): error TS2567: Enum declarations can only merge with namespace or other enum declarations.
1212
tests/cases/compiler/augmentedTypesFunction.ts(21,6): error TS2567: Enum declarations can only merge with namespace or other enum declarations.
1313

@@ -39,21 +39,21 @@ tests/cases/compiler/augmentedTypesFunction.ts(21,6): error TS2567: Enum declara
3939
// function then class
4040
function y3() { } // error
4141
~~
42-
!!! error TS2300: Duplicate identifier 'y3'.
43-
!!! related TS6203 tests/cases/compiler/augmentedTypesFunction.ts:14:7: 'y3' was also declared here.
42+
!!! error TS2814: Function with bodies can only merge with classes that are ambient.
43+
!!! related TS6506 tests/cases/compiler/augmentedTypesFunction.ts:14:7: Consider adding a 'declare' modifier to this class.
4444
class y3 { } // error
4545
~~
46-
!!! error TS2300: Duplicate identifier 'y3'.
47-
!!! related TS6203 tests/cases/compiler/augmentedTypesFunction.ts:13:10: 'y3' was also declared here.
46+
!!! error TS2813: Class declaration cannot implement overload list for 'y3'.
47+
!!! related TS6506 tests/cases/compiler/augmentedTypesFunction.ts:14:7: Consider adding a 'declare' modifier to this class.
4848

4949
function y3a() { } // error
5050
~~~
51-
!!! error TS2300: Duplicate identifier 'y3a'.
52-
!!! related TS6203 tests/cases/compiler/augmentedTypesFunction.ts:17:7: 'y3a' was also declared here.
51+
!!! error TS2814: Function with bodies can only merge with classes that are ambient.
52+
!!! related TS6506 tests/cases/compiler/augmentedTypesFunction.ts:17:7: Consider adding a 'declare' modifier to this class.
5353
class y3a { public foo() { } } // error
5454
~~~
55-
!!! error TS2300: Duplicate identifier 'y3a'.
56-
!!! related TS6203 tests/cases/compiler/augmentedTypesFunction.ts:16:10: 'y3a' was also declared here.
55+
!!! error TS2813: Class declaration cannot implement overload list for 'y3a'.
56+
!!! related TS6506 tests/cases/compiler/augmentedTypesFunction.ts:17:7: Consider adding a 'declare' modifier to this class.
5757

5858
// function then enum
5959
function y4() { } // error

tests/baselines/reference/callOverloads1.errors.txt

+7-7
Original file line numberDiff line numberDiff line change
@@ -1,13 +1,13 @@
1-
tests/cases/compiler/callOverloads1.ts(1,7): error TS2300: Duplicate identifier 'Foo'.
2-
tests/cases/compiler/callOverloads1.ts(9,10): error TS2300: Duplicate identifier 'Foo'.
1+
tests/cases/compiler/callOverloads1.ts(1,7): error TS2813: Class declaration cannot implement overload list for 'Foo'.
32
tests/cases/compiler/callOverloads1.ts(9,10): error TS2391: Function implementation is missing or not immediately following the declaration.
3+
tests/cases/compiler/callOverloads1.ts(9,10): error TS2814: Function with bodies can only merge with classes that are ambient.
44

55

66
==== tests/cases/compiler/callOverloads1.ts (3 errors) ====
77
class Foo { // error
88
~~~
9-
!!! error TS2300: Duplicate identifier 'Foo'.
10-
!!! related TS6203 tests/cases/compiler/callOverloads1.ts:9:10: 'Foo' was also declared here.
9+
!!! error TS2813: Class declaration cannot implement overload list for 'Foo'.
10+
!!! related TS6506 tests/cases/compiler/callOverloads1.ts:1:7: Consider adding a 'declare' modifier to this class.
1111
bar1() { /*WScript.Echo("bar1");*/ }
1212

1313
constructor(x: any) {
@@ -17,10 +17,10 @@ tests/cases/compiler/callOverloads1.ts(9,10): error TS2391: Function implementat
1717

1818
function Foo(); // error
1919
~~~
20-
!!! error TS2300: Duplicate identifier 'Foo'.
21-
!!! related TS6203 tests/cases/compiler/callOverloads1.ts:1:7: 'Foo' was also declared here.
22-
~~~
2320
!!! error TS2391: Function implementation is missing or not immediately following the declaration.
21+
~~~
22+
!!! error TS2814: Function with bodies can only merge with classes that are ambient.
23+
!!! related TS6506 tests/cases/compiler/callOverloads1.ts:1:7: Consider adding a 'declare' modifier to this class.
2424
function F1(s:string);
2525
function F1(a:any) { return a;}
2626

tests/baselines/reference/callOverloads2.errors.txt

+6-6
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,5 @@
1-
tests/cases/compiler/callOverloads2.ts(1,7): error TS2300: Duplicate identifier 'Foo'.
2-
tests/cases/compiler/callOverloads2.ts(9,10): error TS2300: Duplicate identifier 'Foo'.
1+
tests/cases/compiler/callOverloads2.ts(1,7): error TS2813: Class declaration cannot implement overload list for 'Foo'.
2+
tests/cases/compiler/callOverloads2.ts(9,10): error TS2814: Function with bodies can only merge with classes that are ambient.
33
tests/cases/compiler/callOverloads2.ts(11,10): error TS2389: Function implementation name must be 'Foo'.
44
tests/cases/compiler/callOverloads2.ts(11,10): error TS2393: Duplicate function implementation.
55
tests/cases/compiler/callOverloads2.ts(12,10): error TS2393: Duplicate function implementation.
@@ -9,8 +9,8 @@ tests/cases/compiler/callOverloads2.ts(14,10): error TS2391: Function implementa
99
==== tests/cases/compiler/callOverloads2.ts (6 errors) ====
1010
class Foo { // error
1111
~~~
12-
!!! error TS2300: Duplicate identifier 'Foo'.
13-
!!! related TS6203 tests/cases/compiler/callOverloads2.ts:9:10: 'Foo' was also declared here.
12+
!!! error TS2813: Class declaration cannot implement overload list for 'Foo'.
13+
!!! related TS6506 tests/cases/compiler/callOverloads2.ts:1:7: Consider adding a 'declare' modifier to this class.
1414
bar1() { /*WScript.Echo("bar1");*/ }
1515

1616
constructor(x: any) {
@@ -20,8 +20,8 @@ tests/cases/compiler/callOverloads2.ts(14,10): error TS2391: Function implementa
2020

2121
function Foo(); // error
2222
~~~
23-
!!! error TS2300: Duplicate identifier 'Foo'.
24-
!!! related TS6203 tests/cases/compiler/callOverloads2.ts:1:7: 'Foo' was also declared here.
23+
!!! error TS2814: Function with bodies can only merge with classes that are ambient.
24+
!!! related TS6506 tests/cases/compiler/callOverloads2.ts:1:7: Consider adding a 'declare' modifier to this class.
2525

2626
function F1(s:string) {return s;} // error
2727
~~

tests/baselines/reference/callOverloads3.errors.txt

+10-13
Original file line numberDiff line numberDiff line change
@@ -1,27 +1,24 @@
1-
tests/cases/compiler/callOverloads3.ts(1,10): error TS2300: Duplicate identifier 'Foo'.
2-
tests/cases/compiler/callOverloads3.ts(2,10): error TS2300: Duplicate identifier 'Foo'.
1+
tests/cases/compiler/callOverloads3.ts(1,10): error TS2814: Function with bodies can only merge with classes that are ambient.
32
tests/cases/compiler/callOverloads3.ts(2,10): error TS2391: Function implementation is missing or not immediately following the declaration.
4-
tests/cases/compiler/callOverloads3.ts(3,7): error TS2300: Duplicate identifier 'Foo'.
3+
tests/cases/compiler/callOverloads3.ts(2,10): error TS2814: Function with bodies can only merge with classes that are ambient.
4+
tests/cases/compiler/callOverloads3.ts(3,7): error TS2813: Class declaration cannot implement overload list for 'Foo'.
55

66

77
==== tests/cases/compiler/callOverloads3.ts (4 errors) ====
88
function Foo():Foo; // error
99
~~~
10-
!!! error TS2300: Duplicate identifier 'Foo'.
11-
!!! related TS6203 tests/cases/compiler/callOverloads3.ts:2:10: 'Foo' was also declared here.
12-
!!! related TS6204 tests/cases/compiler/callOverloads3.ts:3:7: and here.
10+
!!! error TS2814: Function with bodies can only merge with classes that are ambient.
11+
!!! related TS6506 tests/cases/compiler/callOverloads3.ts:3:7: Consider adding a 'declare' modifier to this class.
1312
function Foo(s:string):Foo; // error
1413
~~~
15-
!!! error TS2300: Duplicate identifier 'Foo'.
16-
!!! related TS6203 tests/cases/compiler/callOverloads3.ts:1:10: 'Foo' was also declared here.
17-
!!! related TS6204 tests/cases/compiler/callOverloads3.ts:3:7: and here.
18-
~~~
1914
!!! error TS2391: Function implementation is missing or not immediately following the declaration.
15+
~~~
16+
!!! error TS2814: Function with bodies can only merge with classes that are ambient.
17+
!!! related TS6506 tests/cases/compiler/callOverloads3.ts:3:7: Consider adding a 'declare' modifier to this class.
2018
class Foo { // error
2119
~~~
22-
!!! error TS2300: Duplicate identifier 'Foo'.
23-
!!! related TS6203 tests/cases/compiler/callOverloads3.ts:1:10: 'Foo' was also declared here.
24-
!!! related TS6204 tests/cases/compiler/callOverloads3.ts:2:10: and here.
20+
!!! error TS2813: Class declaration cannot implement overload list for 'Foo'.
21+
!!! related TS6506 tests/cases/compiler/callOverloads3.ts:3:7: Consider adding a 'declare' modifier to this class.
2522
bar1() { /*WScript.Echo("bar1");*/ }
2623
constructor(x: any) {
2724
// WScript.Echo("Constructor function has executed");

tests/baselines/reference/callOverloads4.errors.txt

+10-13
Original file line numberDiff line numberDiff line change
@@ -1,27 +1,24 @@
1-
tests/cases/compiler/callOverloads4.ts(1,10): error TS2300: Duplicate identifier 'Foo'.
2-
tests/cases/compiler/callOverloads4.ts(2,10): error TS2300: Duplicate identifier 'Foo'.
1+
tests/cases/compiler/callOverloads4.ts(1,10): error TS2814: Function with bodies can only merge with classes that are ambient.
32
tests/cases/compiler/callOverloads4.ts(2,10): error TS2391: Function implementation is missing or not immediately following the declaration.
4-
tests/cases/compiler/callOverloads4.ts(3,7): error TS2300: Duplicate identifier 'Foo'.
3+
tests/cases/compiler/callOverloads4.ts(2,10): error TS2814: Function with bodies can only merge with classes that are ambient.
4+
tests/cases/compiler/callOverloads4.ts(3,7): error TS2813: Class declaration cannot implement overload list for 'Foo'.
55

66

77
==== tests/cases/compiler/callOverloads4.ts (4 errors) ====
88
function Foo():Foo; // error
99
~~~
10-
!!! error TS2300: Duplicate identifier 'Foo'.
11-
!!! related TS6203 tests/cases/compiler/callOverloads4.ts:2:10: 'Foo' was also declared here.
12-
!!! related TS6204 tests/cases/compiler/callOverloads4.ts:3:7: and here.
10+
!!! error TS2814: Function with bodies can only merge with classes that are ambient.
11+
!!! related TS6506 tests/cases/compiler/callOverloads4.ts:3:7: Consider adding a 'declare' modifier to this class.
1312
function Foo(s:string):Foo; // error
1413
~~~
15-
!!! error TS2300: Duplicate identifier 'Foo'.
16-
!!! related TS6203 tests/cases/compiler/callOverloads4.ts:1:10: 'Foo' was also declared here.
17-
!!! related TS6204 tests/cases/compiler/callOverloads4.ts:3:7: and here.
18-
~~~
1914
!!! error TS2391: Function implementation is missing or not immediately following the declaration.
15+
~~~
16+
!!! error TS2814: Function with bodies can only merge with classes that are ambient.
17+
!!! related TS6506 tests/cases/compiler/callOverloads4.ts:3:7: Consider adding a 'declare' modifier to this class.
2018
class Foo { // error
2119
~~~
22-
!!! error TS2300: Duplicate identifier 'Foo'.
23-
!!! related TS6203 tests/cases/compiler/callOverloads4.ts:1:10: 'Foo' was also declared here.
24-
!!! related TS6204 tests/cases/compiler/callOverloads4.ts:2:10: and here.
20+
!!! error TS2813: Class declaration cannot implement overload list for 'Foo'.
21+
!!! related TS6506 tests/cases/compiler/callOverloads4.ts:3:7: Consider adding a 'declare' modifier to this class.
2522
bar1() { /*WScript.Echo("bar1");*/ }
2623
constructor(s: string);
2724
constructor(x: any) {

tests/baselines/reference/callOverloads5.errors.txt

+10-13
Original file line numberDiff line numberDiff line change
@@ -1,27 +1,24 @@
1-
tests/cases/compiler/callOverloads5.ts(1,10): error TS2300: Duplicate identifier 'Foo'.
2-
tests/cases/compiler/callOverloads5.ts(2,10): error TS2300: Duplicate identifier 'Foo'.
1+
tests/cases/compiler/callOverloads5.ts(1,10): error TS2814: Function with bodies can only merge with classes that are ambient.
32
tests/cases/compiler/callOverloads5.ts(2,10): error TS2391: Function implementation is missing or not immediately following the declaration.
4-
tests/cases/compiler/callOverloads5.ts(3,7): error TS2300: Duplicate identifier 'Foo'.
3+
tests/cases/compiler/callOverloads5.ts(2,10): error TS2814: Function with bodies can only merge with classes that are ambient.
4+
tests/cases/compiler/callOverloads5.ts(3,7): error TS2813: Class declaration cannot implement overload list for 'Foo'.
55

66

77
==== tests/cases/compiler/callOverloads5.ts (4 errors) ====
88
function Foo():Foo; // error
99
~~~
10-
!!! error TS2300: Duplicate identifier 'Foo'.
11-
!!! related TS6203 tests/cases/compiler/callOverloads5.ts:2:10: 'Foo' was also declared here.
12-
!!! related TS6204 tests/cases/compiler/callOverloads5.ts:3:7: and here.
10+
!!! error TS2814: Function with bodies can only merge with classes that are ambient.
11+
!!! related TS6506 tests/cases/compiler/callOverloads5.ts:3:7: Consider adding a 'declare' modifier to this class.
1312
function Foo(s:string):Foo; // error
1413
~~~
15-
!!! error TS2300: Duplicate identifier 'Foo'.
16-
!!! related TS6203 tests/cases/compiler/callOverloads5.ts:1:10: 'Foo' was also declared here.
17-
!!! related TS6204 tests/cases/compiler/callOverloads5.ts:3:7: and here.
18-
~~~
1914
!!! error TS2391: Function implementation is missing or not immediately following the declaration.
15+
~~~
16+
!!! error TS2814: Function with bodies can only merge with classes that are ambient.
17+
!!! related TS6506 tests/cases/compiler/callOverloads5.ts:3:7: Consider adding a 'declare' modifier to this class.
2018
class Foo { // error
2119
~~~
22-
!!! error TS2300: Duplicate identifier 'Foo'.
23-
!!! related TS6203 tests/cases/compiler/callOverloads5.ts:1:10: 'Foo' was also declared here.
24-
!!! related TS6204 tests/cases/compiler/callOverloads5.ts:2:10: and here.
20+
!!! error TS2813: Class declaration cannot implement overload list for 'Foo'.
21+
!!! related TS6506 tests/cases/compiler/callOverloads5.ts:3:7: Consider adding a 'declare' modifier to this class.
2522
bar1(s:string);
2623
bar1(n:number);
2724
bar1(a:any) { /*WScript.Echo(a);*/ }

0 commit comments

Comments
 (0)