File tree Expand file tree Collapse file tree 2 files changed +20
-0
lines changed Expand file tree Collapse file tree 2 files changed +20
-0
lines changed Original file line number Diff line number Diff line change @@ -3866,6 +3866,19 @@ module ts {
38663866 }
38673867
38683868 function instantiateAnonymousType(type: ObjectType, mapper: TypeMapper): ObjectType {
3869+ // If this type has already been instantiated using this mapper, returned the cached result. This guards against
3870+ // infinite instantiations of cyclic types, e.g. "var x: { a: T, b: typeof x };"
3871+ if (mapper.mappings) {
3872+ for (let mapping of mapper.mappings) {
3873+ if (mapping.type === type) {
3874+ return mapping.result;
3875+ }
3876+ }
3877+ }
3878+ else {
3879+ mapper.mappings = [];
3880+ }
3881+ // Instantiate the given type using the given mapper and cache the result
38693882 let result = <ResolvedType>createObjectType(TypeFlags.Anonymous, type.symbol);
38703883 result.properties = instantiateList(getPropertiesOfObjectType(type), mapper, instantiateSymbol);
38713884 result.members = createSymbolTable(result.properties);
@@ -3875,6 +3888,7 @@ module ts {
38753888 let numberIndexType = getIndexTypeOfType(type, IndexKind.Number);
38763889 if (stringIndexType) result.stringIndexType = instantiateType(stringIndexType, mapper);
38773890 if (numberIndexType) result.numberIndexType = instantiateType(numberIndexType, mapper);
3891+ mapper.mappings.push({ type, result });
38783892 return result;
38793893 }
38803894
Original file line number Diff line number Diff line change @@ -1586,9 +1586,15 @@ module ts {
15861586 Number ,
15871587 }
15881588
1589+ export interface TypeMapping {
1590+ type : Type ;
1591+ result : Type ;
1592+ }
1593+
15891594 /* @internal */
15901595 export interface TypeMapper {
15911596 ( t : TypeParameter ) : Type ;
1597+ mappings ?: TypeMapping [ ] ; // Type mapping cache
15921598 }
15931599
15941600 /* @internal */
You can’t perform that action at this time.
0 commit comments