Skip to content

Commit 29cfca3

Browse files
iisaduanjakebailey
andauthored
add pushTypeResolution to getTypeOfAlias (#52642)
Co-authored-by: Jake Bailey <[email protected]>
1 parent 6061069 commit 29cfca3

File tree

6 files changed

+76
-8
lines changed

6 files changed

+76
-8
lines changed

src/compiler/checker.ts

Lines changed: 24 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -11832,9 +11832,13 @@ export function createTypeChecker(host: TypeCheckerHost): TypeChecker {
1183211832
function getTypeOfAlias(symbol: Symbol): Type {
1183311833
const links = getSymbolLinks(symbol);
1183411834
if (!links.type) {
11835+
if (!pushTypeResolution(symbol, TypeSystemPropertyName.Type)) {
11836+
return errorType;
11837+
}
1183511838
const targetSymbol = resolveAlias(symbol);
1183611839
const exportSymbol = symbol.declarations && getTargetOfAliasDeclaration(getDeclarationOfAliasSymbol(symbol)!, /*dontRecursivelyResolve*/ true);
1183711840
const declaredType = firstDefined(exportSymbol?.declarations, d => isExportAssignment(d) ? tryGetTypeFromEffectiveTypeNode(d) : undefined);
11841+
1183811842
// It only makes sense to get the type of a value symbol. If the result of resolving
1183911843
// the alias is not a value, then it has no type. To get the type associated with a
1184011844
// type symbol, call getDeclaredTypeOfSymbol.
@@ -11845,6 +11849,11 @@ export function createTypeChecker(host: TypeCheckerHost): TypeChecker {
1184511849
: declaredType ? declaredType
1184611850
: getSymbolFlags(targetSymbol) & SymbolFlags.Value ? getTypeOfSymbol(targetSymbol)
1184711851
: errorType;
11852+
11853+
if (!popTypeResolution()) {
11854+
reportCircularityError(exportSymbol ?? symbol);
11855+
return links.type = errorType;
11856+
}
1184811857
}
1184911858
return links.type;
1185011859
}
@@ -11860,15 +11869,23 @@ export function createTypeChecker(host: TypeCheckerHost): TypeChecker {
1186011869
}
1186111870

1186211871
function reportCircularityError(symbol: Symbol) {
11863-
const declaration = symbol.valueDeclaration as VariableLikeDeclaration;
11872+
const declaration = symbol.valueDeclaration;
1186411873
// Check if variable has type annotation that circularly references the variable itself
11865-
if (getEffectiveTypeAnnotationNode(declaration)) {
11866-
error(symbol.valueDeclaration, Diagnostics._0_is_referenced_directly_or_indirectly_in_its_own_type_annotation, symbolToString(symbol));
11867-
return errorType;
11874+
if (declaration) {
11875+
if (getEffectiveTypeAnnotationNode(declaration)) {
11876+
error(symbol.valueDeclaration, Diagnostics._0_is_referenced_directly_or_indirectly_in_its_own_type_annotation, symbolToString(symbol));
11877+
return errorType;
11878+
}
11879+
// Check if variable has initializer that circularly references the variable itself
11880+
if (noImplicitAny && (declaration.kind !== SyntaxKind.Parameter || (declaration as HasInitializer).initializer)) {
11881+
error(symbol.valueDeclaration, Diagnostics._0_implicitly_has_type_any_because_it_does_not_have_a_type_annotation_and_is_referenced_directly_or_indirectly_in_its_own_initializer, symbolToString(symbol));
11882+
}
1186811883
}
11869-
// Check if variable has initializer that circularly references the variable itself
11870-
if (noImplicitAny && (declaration.kind !== SyntaxKind.Parameter || (declaration as HasInitializer).initializer)) {
11871-
error(symbol.valueDeclaration, Diagnostics._0_implicitly_has_type_any_because_it_does_not_have_a_type_annotation_and_is_referenced_directly_or_indirectly_in_its_own_initializer, symbolToString(symbol));
11884+
else if (symbol.flags & SymbolFlags.Alias) {
11885+
const node = getDeclarationOfAliasSymbol(symbol);
11886+
if (node) {
11887+
error(node, Diagnostics.Circular_definition_of_import_alias_0, symbolToString(symbol));
11888+
}
1187211889
}
1187311890
// Circularities could also result from parameters in function expressions that end up
1187411891
// having themselves as contextual types following type argument inference. In those cases
Lines changed: 11 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,11 @@
1+
bar.js(2,1): error TS2303: Circular definition of import alias 'blah'.
2+
bar.js(2,24): error TS2339: Property 'someProp' does not exist on type '{ (): void; blah: any; }'.
3+
4+
5+
==== bar.js (2 errors) ====
6+
module.exports = function () {};
7+
exports.blah = exports.someProp;
8+
~~~~~~~~~~~~
9+
!!! error TS2303: Circular definition of import alias 'blah'.
10+
~~~~~~~~
11+
!!! error TS2339: Property 'someProp' does not exist on type '{ (): void; blah: any; }'.
Lines changed: 14 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,14 @@
1+
//// [tests/cases/compiler/pushTypeGetTypeOfAlias.ts] ////
2+
3+
=== bar.js ===
4+
module.exports = function () {};
5+
>module.exports : Symbol(module.exports, Decl(bar.js, 0, 0))
6+
>module : Symbol(export=, Decl(bar.js, 0, 0))
7+
>exports : Symbol(export=, Decl(bar.js, 0, 0))
8+
9+
exports.blah = exports.someProp;
10+
>exports.blah : Symbol(blah, Decl(bar.js, 0, 32))
11+
>exports : Symbol(blah, Decl(bar.js, 0, 32))
12+
>blah : Symbol(blah, Decl(bar.js, 0, 32))
13+
>exports : Symbol("bar", Decl(bar.js, 0, 0))
14+
Lines changed: 19 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,19 @@
1+
//// [tests/cases/compiler/pushTypeGetTypeOfAlias.ts] ////
2+
3+
=== bar.js ===
4+
module.exports = function () {};
5+
>module.exports = function () {} : { (): void; blah: any; }
6+
>module.exports : { (): void; blah: any; }
7+
>module : { exports: { (): void; blah: any; }; }
8+
>exports : { (): void; blah: any; }
9+
>function () {} : () => void
10+
11+
exports.blah = exports.someProp;
12+
>exports.blah = exports.someProp : any
13+
>exports.blah : any
14+
>exports : { (): void; blah: any; }
15+
>blah : any
16+
>exports.someProp : any
17+
>exports : { (): void; blah: any; }
18+
>someProp : any
19+

tests/baselines/reference/recursiveExportAssignmentAndFindAliasedType7.types

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -16,7 +16,7 @@ import self = require("recursiveExportAssignmentAndFindAliasedType7_moduleD");
1616

1717
var selfVar = self;
1818
>selfVar : any
19-
>self : any
19+
>self : error
2020

2121
export = selfVar;
2222
>selfVar : any
Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,7 @@
1+
// @checkJs: true
2+
// @allowJs: true
3+
// @noEmit: true
4+
5+
// @Filename: bar.js
6+
module.exports = function () {};
7+
exports.blah = exports.someProp;

0 commit comments

Comments
 (0)