mirror of
https://github.com/microsoft/TypeScript.git
synced 2026-02-15 03:23:08 -06:00
Cache unnormalized intersection types
This commit is contained in:
parent
41a3f83b4e
commit
309ae224f0
@ -391,7 +391,7 @@ namespace ts {
|
||||
|
||||
const tupleTypes = createMap<GenericType>();
|
||||
const unionTypes = createMap<UnionType>();
|
||||
const intersectionTypes = createMap<IntersectionType>();
|
||||
const intersectionTypes = createMap<Type>();
|
||||
const literalTypes = createMap<LiteralType>();
|
||||
const indexedAccessTypes = createMap<IndexedAccessType>();
|
||||
const substitutionTypes = createMap<SubstitutionType>();
|
||||
@ -9838,6 +9838,15 @@ namespace ts {
|
||||
return true;
|
||||
}
|
||||
|
||||
function createIntersectionType(types: Type[], aliasSymbol?: Symbol, aliasTypeArguments?: ReadonlyArray<Type>) {
|
||||
const result = <IntersectionType>createType(TypeFlags.Intersection);
|
||||
result.objectFlags = getPropagatingFlagsOfTypes(types, /*excludeKinds*/ TypeFlags.Nullable);
|
||||
result.types = types;
|
||||
result.aliasSymbol = aliasSymbol; // See comment in `getUnionTypeFromSortedList`.
|
||||
result.aliasTypeArguments = aliasTypeArguments;
|
||||
return result;
|
||||
}
|
||||
|
||||
// We normalize combinations of intersection and union types based on the distributive property of the '&'
|
||||
// operator. Specifically, because X & (A | B) is equivalent to X & A | X & B, we can transform intersection
|
||||
// types with union type constituents into equivalent union types with intersection type constituents and
|
||||
@ -9875,31 +9884,31 @@ namespace ts {
|
||||
if (typeSet.length === 1) {
|
||||
return typeSet[0];
|
||||
}
|
||||
if (includes & TypeFlags.Union) {
|
||||
if (intersectUnionsOfPrimitiveTypes(typeSet)) {
|
||||
// When the intersection creates a reduced set (which might mean that *all* union types have
|
||||
// disappeared), we restart the operation to get a new set of combined flags. Once we have
|
||||
// reduced we'll never reduce again, so this occurs at most once.
|
||||
return getIntersectionType(typeSet, aliasSymbol, aliasTypeArguments);
|
||||
}
|
||||
// We are attempting to construct a type of the form X & (A | B) & Y. Transform this into a type of
|
||||
// the form X & A & Y | X & B & Y and recursively reduce until no union type constituents remain.
|
||||
const unionIndex = findIndex(typeSet, t => (t.flags & TypeFlags.Union) !== 0);
|
||||
const unionType = <UnionType>typeSet[unionIndex];
|
||||
return getUnionType(map(unionType.types, t => getIntersectionType(replaceElement(typeSet, unionIndex, t))),
|
||||
UnionReduction.Literal, aliasSymbol, aliasTypeArguments);
|
||||
}
|
||||
const id = getTypeListId(typeSet);
|
||||
let type = intersectionTypes.get(id);
|
||||
if (!type) {
|
||||
type = <IntersectionType>createType(TypeFlags.Intersection);
|
||||
intersectionTypes.set(id, type);
|
||||
type.objectFlags = getPropagatingFlagsOfTypes(typeSet, /*excludeKinds*/ TypeFlags.Nullable);
|
||||
type.types = typeSet;
|
||||
type.aliasSymbol = aliasSymbol; // See comment in `getUnionTypeFromSortedList`.
|
||||
type.aliasTypeArguments = aliasTypeArguments;
|
||||
let result = intersectionTypes.get(id);
|
||||
if (!result) {
|
||||
if (includes & TypeFlags.Union) {
|
||||
if (intersectUnionsOfPrimitiveTypes(typeSet)) {
|
||||
// When the intersection creates a reduced set (which might mean that *all* union types have
|
||||
// disappeared), we restart the operation to get a new set of combined flags. Once we have
|
||||
// reduced we'll never reduce again, so this occurs at most once.
|
||||
result = getIntersectionType(typeSet, aliasSymbol, aliasTypeArguments);
|
||||
}
|
||||
else {
|
||||
// We are attempting to construct a type of the form X & (A | B) & Y. Transform this into a type of
|
||||
// the form X & A & Y | X & B & Y and recursively reduce until no union type constituents remain.
|
||||
const unionIndex = findIndex(typeSet, t => (t.flags & TypeFlags.Union) !== 0);
|
||||
const unionType = <UnionType>typeSet[unionIndex];
|
||||
result = getUnionType(map(unionType.types, t => getIntersectionType(replaceElement(typeSet, unionIndex, t))),
|
||||
UnionReduction.Literal, aliasSymbol, aliasTypeArguments);
|
||||
}
|
||||
}
|
||||
else {
|
||||
result = createIntersectionType(typeSet, aliasSymbol, aliasTypeArguments);
|
||||
}
|
||||
intersectionTypes.set(id, result);
|
||||
}
|
||||
return type;
|
||||
return result;
|
||||
}
|
||||
|
||||
function getTypeFromIntersectionTypeNode(node: IntersectionTypeNode): Type {
|
||||
|
||||
Loading…
x
Reference in New Issue
Block a user