@@ -4397,8 +4397,8 @@ namespace ts {
4397
4397
context.inferTypeParameters = (<ConditionalType>type).root.inferTypeParameters;
4398
4398
const extendsTypeNode = typeToTypeNodeHelper((<ConditionalType>type).extendsType, context);
4399
4399
context.inferTypeParameters = saveInferTypeParameters;
4400
- const trueTypeNode = typeToTypeNodeHelper (getTrueTypeFromConditionalType(<ConditionalType>type), context );
4401
- const falseTypeNode = typeToTypeNodeHelper (getFalseTypeFromConditionalType(<ConditionalType>type), context );
4400
+ const trueTypeNode = typeToTypeNodeOrCircularityElision (getTrueTypeFromConditionalType(<ConditionalType>type));
4401
+ const falseTypeNode = typeToTypeNodeOrCircularityElision (getFalseTypeFromConditionalType(<ConditionalType>type));
4402
4402
context.approximateLength += 15;
4403
4403
return createConditionalTypeNode(checkTypeNode, extendsTypeNode, trueTypeNode, falseTypeNode);
4404
4404
}
@@ -4408,6 +4408,21 @@ namespace ts {
4408
4408
4409
4409
return Debug.fail("Should be unreachable.");
4410
4410
4411
+
4412
+ function typeToTypeNodeOrCircularityElision(type: Type) {
4413
+ if (type.flags & TypeFlags.Union) {
4414
+ if (context.visitedTypes && context.visitedTypes.has("" + getTypeId(type))) {
4415
+ if (!(context.flags & NodeBuilderFlags.AllowAnonymousIdentifier)) {
4416
+ context.encounteredError = true;
4417
+ context.tracker?.reportCyclicStructureError?.();
4418
+ }
4419
+ return createElidedInformationPlaceholder(context);
4420
+ }
4421
+ return visitAndTransformType(type, type => typeToTypeNodeHelper(type, context));
4422
+ }
4423
+ return typeToTypeNodeHelper(type, context);
4424
+ }
4425
+
4411
4426
function createMappedTypeNodeFromType(type: MappedType) {
4412
4427
Debug.assert(!!(type.flags & TypeFlags.Object));
4413
4428
const readonlyToken = type.declaration.readonlyToken ? <ReadonlyToken | PlusToken | MinusToken>createToken(type.declaration.readonlyToken.kind) : undefined;
@@ -12794,10 +12809,12 @@ namespace ts {
12794
12809
return links.resolvedType;
12795
12810
}
12796
12811
12797
- function createIndexedAccessType(objectType: Type, indexType: Type) {
12812
+ function createIndexedAccessType(objectType: Type, indexType: Type, aliasSymbol: Symbol | undefined, aliasTypeArguments: readonly Type[] | undefined ) {
12798
12813
const type = <IndexedAccessType>createType(TypeFlags.IndexedAccess);
12799
12814
type.objectType = objectType;
12800
12815
type.indexType = indexType;
12816
+ type.aliasSymbol = aliasSymbol;
12817
+ type.aliasTypeArguments = aliasTypeArguments;
12801
12818
return type;
12802
12819
}
12803
12820
@@ -13129,11 +13146,11 @@ namespace ts {
13129
13146
return instantiateType(getTemplateTypeFromMappedType(objectType), templateMapper);
13130
13147
}
13131
13148
13132
- function getIndexedAccessType(objectType: Type, indexType: Type, accessNode?: ElementAccessExpression | IndexedAccessTypeNode | PropertyName | BindingName | SyntheticExpression): Type {
13133
- return getIndexedAccessTypeOrUndefined(objectType, indexType, accessNode, AccessFlags.None) || (accessNode ? errorType : unknownType);
13149
+ function getIndexedAccessType(objectType: Type, indexType: Type, accessNode?: ElementAccessExpression | IndexedAccessTypeNode | PropertyName | BindingName | SyntheticExpression, aliasSymbol?: Symbol, aliasTypeArguments?: readonly Type[] ): Type {
13150
+ return getIndexedAccessTypeOrUndefined(objectType, indexType, accessNode, AccessFlags.None, aliasSymbol, aliasTypeArguments ) || (accessNode ? errorType : unknownType);
13134
13151
}
13135
13152
13136
- function getIndexedAccessTypeOrUndefined(objectType: Type, indexType: Type, accessNode?: ElementAccessExpression | IndexedAccessTypeNode | PropertyName | BindingName | SyntheticExpression, accessFlags = AccessFlags.None): Type | undefined {
13153
+ function getIndexedAccessTypeOrUndefined(objectType: Type, indexType: Type, accessNode?: ElementAccessExpression | IndexedAccessTypeNode | PropertyName | BindingName | SyntheticExpression, accessFlags = AccessFlags.None, aliasSymbol?: Symbol, aliasTypeArguments?: readonly Type[] ): Type | undefined {
13137
13154
if (objectType === wildcardType || indexType === wildcardType) {
13138
13155
return wildcardType;
13139
13156
}
@@ -13155,7 +13172,7 @@ namespace ts {
13155
13172
const id = objectType.id + "," + indexType.id;
13156
13173
let type = indexedAccessTypes.get(id);
13157
13174
if (!type) {
13158
- indexedAccessTypes.set(id, type = createIndexedAccessType(objectType, indexType));
13175
+ indexedAccessTypes.set(id, type = createIndexedAccessType(objectType, indexType, aliasSymbol, aliasTypeArguments ));
13159
13176
}
13160
13177
return type;
13161
13178
}
@@ -13183,7 +13200,7 @@ namespace ts {
13183
13200
if (wasMissingProp) {
13184
13201
return undefined;
13185
13202
}
13186
- return accessFlags & AccessFlags.Writing ? getIntersectionType(propTypes) : getUnionType(propTypes);
13203
+ return accessFlags & AccessFlags.Writing ? getIntersectionType(propTypes, aliasSymbol, aliasTypeArguments ) : getUnionType(propTypes, UnionReduction.Literal, aliasSymbol, aliasTypeArguments );
13187
13204
}
13188
13205
return getPropertyTypeForIndexType(objectType, apparentObjectType, indexType, indexType, /* supressNoImplicitAnyError */ false, accessNode, accessFlags | AccessFlags.CacheSymbol);
13189
13206
}
@@ -13193,7 +13210,8 @@ namespace ts {
13193
13210
if (!links.resolvedType) {
13194
13211
const objectType = getTypeFromTypeNode(node.objectType);
13195
13212
const indexType = getTypeFromTypeNode(node.indexType);
13196
- const resolved = getIndexedAccessType(objectType, indexType, node);
13213
+ const potentialAlias = getAliasSymbolForTypeNode(node);
13214
+ const resolved = getIndexedAccessType(objectType, indexType, node, potentialAlias, getTypeArgumentsForAliasSymbol(potentialAlias));
13197
13215
links.resolvedType = resolved.flags & TypeFlags.IndexedAccess &&
13198
13216
(<IndexedAccessType>resolved).objectType === objectType &&
13199
13217
(<IndexedAccessType>resolved).indexType === indexType ?
@@ -14341,7 +14359,7 @@ namespace ts {
14341
14359
return getIndexType(instantiateType((<IndexType>type).type, mapper));
14342
14360
}
14343
14361
if (flags & TypeFlags.IndexedAccess) {
14344
- return getIndexedAccessType(instantiateType((<IndexedAccessType>type).objectType, mapper), instantiateType((<IndexedAccessType>type).indexType, mapper));
14362
+ return getIndexedAccessType(instantiateType((<IndexedAccessType>type).objectType, mapper), instantiateType((<IndexedAccessType>type).indexType, mapper), /*accessNode*/ undefined, type.aliasSymbol, instantiateTypes(type.aliasTypeArguments, mapper) );
14345
14363
}
14346
14364
if (flags & TypeFlags.Conditional) {
14347
14365
return getConditionalTypeInstantiation(<ConditionalType>type, combineTypeMappers((<ConditionalType>type).mapper, mapper));
0 commit comments