Skip to content

Commit b86dea0

Browse files
authored
Fix crash caused by cyclic defaults (microsoft#30532)
1 parent e72f006 commit b86dea0

6 files changed

+78
-4
lines changed

src/compiler/checker.ts

Lines changed: 4 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -5474,9 +5474,6 @@ namespace ts {
54745474
}
54755475
return type;
54765476
}
5477-
if (declaration.kind === SyntaxKind.ExportAssignment) {
5478-
return widenTypeForVariableLikeDeclaration(checkExpressionCached((<ExportAssignment>declaration).expression), declaration);
5479-
}
54805477

54815478
// Handle variable, parameter or property
54825479
if (!pushTypeResolution(symbol, TypeSystemPropertyName.Type)) {
@@ -5487,7 +5484,10 @@ namespace ts {
54875484
return reportCircularityError(symbol);
54885485
}
54895486
let type: Type | undefined;
5490-
if (isInJSFile(declaration) &&
5487+
if (declaration.kind === SyntaxKind.ExportAssignment) {
5488+
type = widenTypeForVariableLikeDeclaration(checkExpressionCached((<ExportAssignment>declaration).expression), declaration);
5489+
}
5490+
else if (isInJSFile(declaration) &&
54915491
(isCallExpression(declaration) || isBinaryExpression(declaration) || isPropertyAccessExpression(declaration) && isBinaryExpression(declaration.parent))) {
54925492
type = getWidenedTypeFromAssignmentDeclaration(symbol);
54935493
}
Lines changed: 16 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,16 @@
1+
tests/cases/compiler/QSpinner.js(3,1): error TS7022: 'default' implicitly has type 'any' because it does not have a type annotation and is referenced directly or indirectly in its own initializer.
2+
3+
4+
==== tests/cases/compiler/QSpinner.js (1 errors) ====
5+
import DefaultSpinner from './QSpinner'
6+
7+
export default {
8+
~~~~~~~~~~~~~~~~
9+
mixins: [DefaultSpinner],
10+
~~~~~~~~~~~~~~~~~~~~~~~~~~~
11+
name: 'QSpinner'
12+
~~~~~~~~~~~~~~~~~~
13+
}
14+
~
15+
!!! error TS7022: 'default' implicitly has type 'any' because it does not have a type annotation and is referenced directly or indirectly in its own initializer.
16+
Lines changed: 17 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,17 @@
1+
//// [QSpinner.js]
2+
import DefaultSpinner from './QSpinner'
3+
4+
export default {
5+
mixins: [DefaultSpinner],
6+
name: 'QSpinner'
7+
}
8+
9+
10+
//// [QSpinner.js]
11+
"use strict";
12+
exports.__esModule = true;
13+
var QSpinner_1 = require("./QSpinner");
14+
exports["default"] = {
15+
mixins: [QSpinner_1["default"]],
16+
name: 'QSpinner'
17+
};
Lines changed: 13 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,13 @@
1+
=== tests/cases/compiler/QSpinner.js ===
2+
import DefaultSpinner from './QSpinner'
3+
>DefaultSpinner : Symbol(DefaultSpinner, Decl(QSpinner.js, 0, 6))
4+
5+
export default {
6+
mixins: [DefaultSpinner],
7+
>mixins : Symbol(mixins, Decl(QSpinner.js, 2, 16))
8+
>DefaultSpinner : Symbol(DefaultSpinner, Decl(QSpinner.js, 0, 6))
9+
10+
name: 'QSpinner'
11+
>name : Symbol(name, Decl(QSpinner.js, 3, 27))
12+
}
13+
Lines changed: 17 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,17 @@
1+
=== tests/cases/compiler/QSpinner.js ===
2+
import DefaultSpinner from './QSpinner'
3+
>DefaultSpinner : any
4+
5+
export default {
6+
>{ mixins: [DefaultSpinner], name: 'QSpinner'} : { mixins: any[]; name: string; }
7+
8+
mixins: [DefaultSpinner],
9+
>mixins : any[]
10+
>[DefaultSpinner] : any[]
11+
>DefaultSpinner : any
12+
13+
name: 'QSpinner'
14+
>name : string
15+
>'QSpinner' : "QSpinner"
16+
}
17+
Lines changed: 11 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,11 @@
1+
// @allowJs: true
2+
// @checkJs: true
3+
// @strict: true
4+
// @outDir: ./out
5+
// @filename: QSpinner.js
6+
import DefaultSpinner from './QSpinner'
7+
8+
export default {
9+
mixins: [DefaultSpinner],
10+
name: 'QSpinner'
11+
}

0 commit comments

Comments
 (0)