Cache widened types (#31586)

* Cache widened types

* Fix lint
This commit is contained in:
Wesley Wigham
2019-05-28 13:13:46 -07:00
committed by GitHub
parent 63b8c6443f
commit cd09cbbd5e
6 changed files with 386 additions and 9 deletions

View File

@@ -14740,26 +14740,34 @@ namespace ts {
function getWidenedTypeWithContext(type: Type, context: WideningContext | undefined): Type {
if (getObjectFlags(type) & ObjectFlags.RequiresWidening) {
if (context === undefined && type.widened) {
return type.widened;
}
let result: Type | undefined;
if (type.flags & TypeFlags.Nullable) {
return anyType;
result = anyType;
}
if (isObjectLiteralType(type)) {
return getWidenedTypeOfObjectLiteral(type, context);
else if (isObjectLiteralType(type)) {
result = getWidenedTypeOfObjectLiteral(type, context);
}
if (type.flags & TypeFlags.Union) {
else if (type.flags & TypeFlags.Union) {
const unionContext = context || createWideningContext(/*parent*/ undefined, /*propertyName*/ undefined, (<UnionType>type).types);
const widenedTypes = sameMap((<UnionType>type).types, t => t.flags & TypeFlags.Nullable ? t : getWidenedTypeWithContext(t, unionContext));
// Widening an empty object literal transitions from a highly restrictive type to
// a highly inclusive one. For that reason we perform subtype reduction here if the
// union includes empty object types (e.g. reducing {} | string to just {}).
return getUnionType(widenedTypes, some(widenedTypes, isEmptyObjectType) ? UnionReduction.Subtype : UnionReduction.Literal);
result = getUnionType(widenedTypes, some(widenedTypes, isEmptyObjectType) ? UnionReduction.Subtype : UnionReduction.Literal);
}
if (type.flags & TypeFlags.Intersection) {
return getIntersectionType(sameMap((<IntersectionType>type).types, getWidenedType));
else if (type.flags & TypeFlags.Intersection) {
result = getIntersectionType(sameMap((<IntersectionType>type).types, getWidenedType));
}
if (isArrayType(type) || isTupleType(type)) {
return createTypeReference((<TypeReference>type).target, sameMap((<TypeReference>type).typeArguments, getWidenedType));
else if (isArrayType(type) || isTupleType(type)) {
result = createTypeReference((<TypeReference>type).target, sameMap((<TypeReference>type).typeArguments, getWidenedType));
}
if (result && context === undefined) {
type.widened = result;
}
return result || type;
}
return type;
}

View File

@@ -4013,6 +4013,8 @@ namespace ts {
restrictiveInstantiation?: Type; // Instantiation with type parameters mapped to unconstrained form
/* @internal */
immediateBaseConstraint?: Type; // Immediate base constraint cache
/* @internal */
widened?: Type; // Cached widened form of the type
}
/* @internal */