Skip to content

Commit b693180

Browse files
committed
Issue an error when a derived class precedes its base class
1 parent 5433553 commit b693180

40 files changed

+1380
-27771
lines changed

src/compiler/checker.ts

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -15179,6 +15179,12 @@ namespace ts {
1517915179
checkTypeAssignableTo(staticType, getTypeWithoutSignatures(staticBaseType), node.name || node,
1518015180
Diagnostics.Class_static_side_0_incorrectly_extends_base_class_static_side_1);
1518115181

15182+
if (baseType.symbol.valueDeclaration && !(baseType.symbol.valueDeclaration.flags & NodeFlags.Ambient)) {
15183+
if (!isBlockScopedNameDeclaredBeforeUse(baseType.symbol.valueDeclaration, node)) {
15184+
error(baseTypeNode, Diagnostics.A_class_must_be_declared_after_its_base_class);
15185+
}
15186+
}
15187+
1518215188
if (!(staticBaseType.symbol && staticBaseType.symbol.flags & SymbolFlags.Class)) {
1518315189
// When the static base type is a "class-like" constructor function (but not actually a class), we verify
1518415190
// that all instantiated base constructor signatures return the same type. We can simply compare the type

src/compiler/diagnosticMessages.json

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1923,6 +1923,10 @@
19231923
"category": "Error",
19241924
"code": 2685
19251925
},
1926+
"A class must be declared after its base class.": {
1927+
"category": "Error",
1928+
"code": 2686
1929+
},
19261930
"Import declaration '{0}' is using private name '{1}'.": {
19271931
"category": "Error",
19281932
"code": 4000
Lines changed: 35 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,35 @@
1+
tests/cases/compiler/baseTypeWrappingInstantiationChain.ts(1,21): error TS2686: A class must be declared after its base class.
2+
tests/cases/compiler/baseTypeWrappingInstantiationChain.ts(12,25): error TS2686: A class must be declared after its base class.
3+
4+
5+
==== tests/cases/compiler/baseTypeWrappingInstantiationChain.ts (2 errors) ====
6+
class C<T1> extends CBase<T1> {
7+
~~~~~~~~~
8+
!!! error TS2686: A class must be declared after its base class.
9+
public works() {
10+
new CBaseBase<Wrapper<T1>>(this);
11+
}
12+
public alsoWorks() {
13+
new CBase<T1>(this); // Should not error, parameter is of type Parameter<Wrapper<T1>>
14+
}
15+
16+
public method(t: Wrapper<T1>) { }
17+
}
18+
19+
class CBase<T2> extends CBaseBase<Wrapper<T2>> {
20+
~~~~~~~~~~~~~~~~~~~~~~
21+
!!! error TS2686: A class must be declared after its base class.
22+
23+
}
24+
25+
class CBaseBase<T3> {
26+
constructor(x: Parameter<T3>) { }
27+
}
28+
29+
class Parameter<T4> {
30+
method(t: T4) { }
31+
}
32+
33+
class Wrapper<T5> {
34+
property: T5;
35+
}

tests/baselines/reference/baseTypeWrappingInstantiationChain.symbols

Lines changed: 0 additions & 69 deletions
This file was deleted.

tests/baselines/reference/baseTypeWrappingInstantiationChain.types

Lines changed: 0 additions & 71 deletions
This file was deleted.
Lines changed: 25 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,25 @@
1+
tests/cases/conformance/internalModules/importDeclarations/circularImportAlias.ts(5,28): error TS2686: A class must be declared after its base class.
2+
3+
4+
==== tests/cases/conformance/internalModules/importDeclarations/circularImportAlias.ts (1 errors) ====
5+
// expected no error
6+
7+
module B {
8+
export import a = A;
9+
export class D extends a.C {
10+
~~~
11+
!!! error TS2686: A class must be declared after its base class.
12+
id: number;
13+
}
14+
}
15+
16+
module A {
17+
export class C { name: string }
18+
export import b = B;
19+
}
20+
21+
var c: { name: string };
22+
var c = new B.a.C();
23+
24+
25+

tests/baselines/reference/circularImportAlias.symbols

Lines changed: 0 additions & 47 deletions
This file was deleted.

tests/baselines/reference/circularImportAlias.types

Lines changed: 0 additions & 48 deletions
This file was deleted.
Lines changed: 15 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,15 @@
1+
tests/cases/conformance/classes/classExpressions/classExpression3.ts(1,23): error TS2686: A class must be declared after its base class.
2+
tests/cases/conformance/classes/classExpressions/classExpression3.ts(1,37): error TS2686: A class must be declared after its base class.
3+
4+
5+
==== tests/cases/conformance/classes/classExpressions/classExpression3.ts (2 errors) ====
6+
let C = class extends class extends class { a = 1 } { b = 2 } { c = 3 };
7+
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
8+
!!! error TS2686: A class must be declared after its base class.
9+
~~~~~~~~~~~~~~~
10+
!!! error TS2686: A class must be declared after its base class.
11+
let c = new C();
12+
c.a;
13+
c.b;
14+
c.c;
15+

tests/baselines/reference/classExpression3.symbols

Lines changed: 0 additions & 26 deletions
This file was deleted.

0 commit comments

Comments
 (0)