Skip to content

Commit 58ed72f

Browse files
committed
Fixes #10624
1 parent db0ee4f commit 58ed72f

12 files changed

+186
-35
lines changed

src/compiler/checker.ts

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -17114,7 +17114,9 @@ namespace ts {
1711417114
checkTypeAssignableTo(staticType, getTypeWithoutSignatures(staticBaseType), node.name || node,
1711517115
Diagnostics.Class_static_side_0_incorrectly_extends_base_class_static_side_1);
1711617116

17117-
if (baseType.symbol.valueDeclaration && !isInAmbientContext(baseType.symbol.valueDeclaration)) {
17117+
if (baseType.symbol.valueDeclaration &&
17118+
!isInAmbientContext(baseType.symbol.valueDeclaration) &&
17119+
baseType.symbol.valueDeclaration.kind === SyntaxKind.ClassDeclaration) {
1711817120
if (!isBlockScopedNameDeclaredBeforeUse(baseType.symbol.valueDeclaration, node)) {
1711917121
error(baseTypeNode, Diagnostics.A_class_must_be_declared_after_its_base_class);
1712017122
}
Lines changed: 30 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,30 @@
1+
//// [classDeclaredBeforeClassFactory.ts]
2+
// Should be OK due to hoisting
3+
class Derived extends makeBaseClass() {}
4+
5+
function makeBaseClass() {
6+
return class Base {};
7+
}
8+
9+
10+
//// [classDeclaredBeforeClassFactory.js]
11+
var __extends = (this && this.__extends) || function (d, b) {
12+
for (var p in b) if (b.hasOwnProperty(p)) d[p] = b[p];
13+
function __() { this.constructor = d; }
14+
d.prototype = b === null ? Object.create(b) : (__.prototype = b.prototype, new __());
15+
};
16+
// Should be OK due to hoisting
17+
var Derived = (function (_super) {
18+
__extends(Derived, _super);
19+
function Derived() {
20+
return _super.apply(this, arguments) || this;
21+
}
22+
return Derived;
23+
}(makeBaseClass()));
24+
function makeBaseClass() {
25+
return (function () {
26+
function Base() {
27+
}
28+
return Base;
29+
}());
30+
}
Lines changed: 13 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,13 @@
1+
=== tests/cases/compiler/classDeclaredBeforeClassFactory.ts ===
2+
// Should be OK due to hoisting
3+
class Derived extends makeBaseClass() {}
4+
>Derived : Symbol(Derived, Decl(classDeclaredBeforeClassFactory.ts, 0, 0))
5+
>makeBaseClass : Symbol(makeBaseClass, Decl(classDeclaredBeforeClassFactory.ts, 1, 40))
6+
7+
function makeBaseClass() {
8+
>makeBaseClass : Symbol(makeBaseClass, Decl(classDeclaredBeforeClassFactory.ts, 1, 40))
9+
10+
return class Base {};
11+
>Base : Symbol(Base, Decl(classDeclaredBeforeClassFactory.ts, 4, 10))
12+
}
13+
Lines changed: 15 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,15 @@
1+
=== tests/cases/compiler/classDeclaredBeforeClassFactory.ts ===
2+
// Should be OK due to hoisting
3+
class Derived extends makeBaseClass() {}
4+
>Derived : Derived
5+
>makeBaseClass() : Base
6+
>makeBaseClass : () => typeof Base
7+
8+
function makeBaseClass() {
9+
>makeBaseClass : () => typeof Base
10+
11+
return class Base {};
12+
>class Base {} : typeof Base
13+
>Base : typeof Base
14+
}
15+

tests/baselines/reference/classExpression3.errors.txt

Lines changed: 0 additions & 15 deletions
This file was deleted.
Lines changed: 26 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,26 @@
1+
=== tests/cases/conformance/classes/classExpressions/classExpression3.ts ===
2+
let C = class extends class extends class { a = 1 } { b = 2 } { c = 3 };
3+
>C : Symbol(C, Decl(classExpression3.ts, 0, 3))
4+
>a : Symbol((Anonymous class).a, Decl(classExpression3.ts, 0, 43))
5+
>b : Symbol((Anonymous class).b, Decl(classExpression3.ts, 0, 53))
6+
>c : Symbol((Anonymous class).c, Decl(classExpression3.ts, 0, 63))
7+
8+
let c = new C();
9+
>c : Symbol(c, Decl(classExpression3.ts, 1, 3))
10+
>C : Symbol(C, Decl(classExpression3.ts, 0, 3))
11+
12+
c.a;
13+
>c.a : Symbol((Anonymous class).a, Decl(classExpression3.ts, 0, 43))
14+
>c : Symbol(c, Decl(classExpression3.ts, 1, 3))
15+
>a : Symbol((Anonymous class).a, Decl(classExpression3.ts, 0, 43))
16+
17+
c.b;
18+
>c.b : Symbol((Anonymous class).b, Decl(classExpression3.ts, 0, 53))
19+
>c : Symbol(c, Decl(classExpression3.ts, 1, 3))
20+
>b : Symbol((Anonymous class).b, Decl(classExpression3.ts, 0, 53))
21+
22+
c.c;
23+
>c.c : Symbol((Anonymous class).c, Decl(classExpression3.ts, 0, 63))
24+
>c : Symbol(c, Decl(classExpression3.ts, 1, 3))
25+
>c : Symbol((Anonymous class).c, Decl(classExpression3.ts, 0, 63))
26+
Lines changed: 33 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,33 @@
1+
=== tests/cases/conformance/classes/classExpressions/classExpression3.ts ===
2+
let C = class extends class extends class { a = 1 } { b = 2 } { c = 3 };
3+
>C : typeof (Anonymous class)
4+
>class extends class extends class { a = 1 } { b = 2 } { c = 3 } : typeof (Anonymous class)
5+
>class extends class { a = 1 } { b = 2 } : (Anonymous class)
6+
>class { a = 1 } : (Anonymous class)
7+
>a : number
8+
>1 : 1
9+
>b : number
10+
>2 : 2
11+
>c : number
12+
>3 : 3
13+
14+
let c = new C();
15+
>c : (Anonymous class)
16+
>new C() : (Anonymous class)
17+
>C : typeof (Anonymous class)
18+
19+
c.a;
20+
>c.a : number
21+
>c : (Anonymous class)
22+
>a : number
23+
24+
c.b;
25+
>c.b : number
26+
>c : (Anonymous class)
27+
>b : number
28+
29+
c.c;
30+
>c.c : number
31+
>c : (Anonymous class)
32+
>c : number
33+

tests/baselines/reference/classExpressionES63.errors.txt

Lines changed: 0 additions & 15 deletions
This file was deleted.
Lines changed: 26 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,26 @@
1+
=== tests/cases/conformance/es6/classExpressions/classExpressionES63.ts ===
2+
let C = class extends class extends class { a = 1 } { b = 2 } { c = 3 };
3+
>C : Symbol(C, Decl(classExpressionES63.ts, 0, 3))
4+
>a : Symbol((Anonymous class).a, Decl(classExpressionES63.ts, 0, 43))
5+
>b : Symbol((Anonymous class).b, Decl(classExpressionES63.ts, 0, 53))
6+
>c : Symbol((Anonymous class).c, Decl(classExpressionES63.ts, 0, 63))
7+
8+
let c = new C();
9+
>c : Symbol(c, Decl(classExpressionES63.ts, 1, 3))
10+
>C : Symbol(C, Decl(classExpressionES63.ts, 0, 3))
11+
12+
c.a;
13+
>c.a : Symbol((Anonymous class).a, Decl(classExpressionES63.ts, 0, 43))
14+
>c : Symbol(c, Decl(classExpressionES63.ts, 1, 3))
15+
>a : Symbol((Anonymous class).a, Decl(classExpressionES63.ts, 0, 43))
16+
17+
c.b;
18+
>c.b : Symbol((Anonymous class).b, Decl(classExpressionES63.ts, 0, 53))
19+
>c : Symbol(c, Decl(classExpressionES63.ts, 1, 3))
20+
>b : Symbol((Anonymous class).b, Decl(classExpressionES63.ts, 0, 53))
21+
22+
c.c;
23+
>c.c : Symbol((Anonymous class).c, Decl(classExpressionES63.ts, 0, 63))
24+
>c : Symbol(c, Decl(classExpressionES63.ts, 1, 3))
25+
>c : Symbol((Anonymous class).c, Decl(classExpressionES63.ts, 0, 63))
26+
Lines changed: 33 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,33 @@
1+
=== tests/cases/conformance/es6/classExpressions/classExpressionES63.ts ===
2+
let C = class extends class extends class { a = 1 } { b = 2 } { c = 3 };
3+
>C : typeof (Anonymous class)
4+
>class extends class extends class { a = 1 } { b = 2 } { c = 3 } : typeof (Anonymous class)
5+
>class extends class { a = 1 } { b = 2 } : (Anonymous class)
6+
>class { a = 1 } : (Anonymous class)
7+
>a : number
8+
>1 : 1
9+
>b : number
10+
>2 : 2
11+
>c : number
12+
>3 : 3
13+
14+
let c = new C();
15+
>c : (Anonymous class)
16+
>new C() : (Anonymous class)
17+
>C : typeof (Anonymous class)
18+
19+
c.a;
20+
>c.a : number
21+
>c : (Anonymous class)
22+
>a : number
23+
24+
c.b;
25+
>c.b : number
26+
>c : (Anonymous class)
27+
>b : number
28+
29+
c.c;
30+
>c.c : number
31+
>c : (Anonymous class)
32+
>c : number
33+

0 commit comments

Comments
 (0)