Skip to content

Commit 59e4770

Browse files
authored
Fix enum tag circular references (#27161)
* Fix enum tag circular references Also, don't try to resolve enum tag types in Typescript. * Improve comment
1 parent e3026b0 commit 59e4770

File tree

7 files changed

+50
-3
lines changed

7 files changed

+50
-3
lines changed

src/compiler/checker.ts

Lines changed: 15 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -640,14 +640,15 @@ namespace ts {
640640
const identityRelation = createMap<RelationComparisonResult>();
641641
const enumRelation = createMap<RelationComparisonResult>();
642642

643-
type TypeSystemEntity = Symbol | Type | Signature;
643+
type TypeSystemEntity = Node | Symbol | Type | Signature;
644644

645645
const enum TypeSystemPropertyName {
646646
Type,
647647
ResolvedBaseConstructorType,
648648
DeclaredType,
649649
ResolvedReturnType,
650650
ImmediateBaseConstraint,
651+
EnumTagType,
651652
}
652653

653654
const enum CheckMode {
@@ -4475,6 +4476,8 @@ namespace ts {
44754476
switch (propertyName) {
44764477
case TypeSystemPropertyName.Type:
44774478
return !!getSymbolLinks(<Symbol>target).type;
4479+
case TypeSystemPropertyName.EnumTagType:
4480+
return !!(getNodeLinks(target as JSDocEnumTag).resolvedEnumType);
44784481
case TypeSystemPropertyName.DeclaredType:
44794482
return !!getSymbolLinks(<Symbol>target).declaredType;
44804483
case TypeSystemPropertyName.ResolvedBaseConstructorType:
@@ -8252,9 +8255,18 @@ namespace ts {
82528255
}
82538256

82548257
// JS are 'string' or 'number', not an enum type.
8255-
const enumTag = symbol.valueDeclaration && getJSDocEnumTag(symbol.valueDeclaration);
8258+
const enumTag = isInJSFile(node) && symbol.valueDeclaration && getJSDocEnumTag(symbol.valueDeclaration);
82568259
if (enumTag) {
8257-
return enumTag.typeExpression ? getTypeFromTypeNode(enumTag.typeExpression) : errorType;
8260+
const links = getNodeLinks(enumTag);
8261+
if (!pushTypeResolution(enumTag, TypeSystemPropertyName.EnumTagType)) {
8262+
return errorType;
8263+
}
8264+
let type = enumTag.typeExpression ? getTypeFromTypeNode(enumTag.typeExpression) : errorType;
8265+
if (!popTypeResolution()) {
8266+
type = errorType;
8267+
error(node, Diagnostics.Enum_type_0_circularly_references_itself, symbolToString(symbol));
8268+
}
8269+
return (links.resolvedEnumType = type);
82588270
}
82598271

82608272
// Get type from reference to named type that cannot be generic (enum or type parameter)

src/compiler/diagnosticMessages.json

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -2112,6 +2112,10 @@
21122112
"category": "Error",
21132113
"code": 2585
21142114
},
2115+
"Enum type '{0}' circularly references itself.": {
2116+
"category": "Error",
2117+
"code": 2586
2118+
},
21152119
"JSX element attributes type '{0}' may not be a union type.": {
21162120
"category": "Error",
21172121
"code": 2600

src/compiler/types.ts

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -3676,6 +3676,7 @@ namespace ts {
36763676
export interface NodeLinks {
36773677
flags: NodeCheckFlags; // Set of flags specific to Node
36783678
resolvedType?: Type; // Cached type of type node
3679+
resolvedEnumType?: Type; // Cached constraint type from enum jsdoc tag
36793680
resolvedSignature?: Signature; // Cached signature of signature node or call expression
36803681
resolvedSignatures?: Map<Signature[]>; // Cached signatures of jsx node
36813682
resolvedSymbol?: Symbol; // Cached name resolution result
Lines changed: 9 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,9 @@
1+
tests/cases/conformance/jsdoc/bug27142.js(1,12): error TS2586: Enum type 'E' circularly references itself.
2+
3+
4+
==== tests/cases/conformance/jsdoc/bug27142.js (1 errors) ====
5+
/** @enum {E} */
6+
~
7+
!!! error TS2586: Enum type 'E' circularly references itself.
8+
const E = { x: 0 };
9+
Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,6 @@
1+
=== tests/cases/conformance/jsdoc/bug27142.js ===
2+
/** @enum {E} */
3+
const E = { x: 0 };
4+
>E : Symbol(E, Decl(bug27142.js, 1, 5))
5+
>x : Symbol(x, Decl(bug27142.js, 1, 11))
6+
Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,8 @@
1+
=== tests/cases/conformance/jsdoc/bug27142.js ===
2+
/** @enum {E} */
3+
const E = { x: 0 };
4+
>E : { x: number; }
5+
>{ x: 0 } : { x: number; }
6+
>x : number
7+
>0 : 0
8+
Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,7 @@
1+
// @noEmit: true
2+
// @allowJs: true
3+
// @checkJs: true
4+
// @Filename: bug27142.js
5+
6+
/** @enum {E} */
7+
const E = { x: 0 };

0 commit comments

Comments
 (0)