Handle circular mapped type instantiations for arrays and tuples

This commit is contained in:
Anders Hejlsberg
2018-10-15 10:18:54 -07:00
parent 6cdba6d351
commit 709f5f2fc4
2 changed files with 12 additions and 1 deletions

View File

@@ -10365,7 +10365,15 @@ namespace ts {
if (typeVariable) {
const mappedTypeVariable = instantiateType(typeVariable, mapper);
if (typeVariable !== mappedTypeVariable) {
return mapType(mappedTypeVariable, t => {
// If we are already in the process of creating an instantiation of this mapped type,
// return the error type. This situation only arises if we are instantiating the mapped
// type for an array or tuple type, as we then need to eagerly resolve the (possibly
// circular) element type(s).
if (type.instantiating) {
return errorType;
}
type.instantiating = true;
const result = mapType(mappedTypeVariable, t => {
if (t.flags & (TypeFlags.AnyOrUnknown | TypeFlags.InstantiableNonPrimitive | TypeFlags.Object | TypeFlags.Intersection) && t !== wildcardType) {
const replacementMapper = createReplacementMapper(typeVariable, t, mapper);
return isArrayType(t) ? createArrayType(instantiateMappedTypeTemplate(type, numberType, /*isOptional*/ true, replacementMapper)) :
@@ -10375,6 +10383,8 @@ namespace ts {
}
return t;
});
type.instantiating = false;
return result;
}
}
return instantiateAnonymousType(type, mapper);

View File

@@ -4074,6 +4074,7 @@ namespace ts {
templateType?: Type;
modifiersType?: Type;
resolvedApparentType?: Type;
instantiating?: boolean;
}
export interface EvolvingArrayType extends ObjectType {