Normalize intersection and union types

This commit is contained in:
Anders Hejlsberg
2016-10-18 11:53:26 -07:00
parent ff17eeda8f
commit ef5f3c90a4
2 changed files with 21 additions and 0 deletions

View File

@@ -5603,6 +5603,11 @@ namespace ts {
}
}
// 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
// effectively ensure that union types are always at the top level in type representations.
//
// We do not perform structural deduplication on intersection types. Intersection types are created only by the &
// type operator and we can't reduce those because we want to support recursive intersection types. For example,
// a type alias of the form "type List<T> = T & { next: List<T> }" cannot be reduced during its declaration.
@@ -5612,6 +5617,16 @@ namespace ts {
if (types.length === 0) {
return emptyObjectType;
}
for (let i = 0; i < types.length; i++) {
const type = types[i];
if (type.flags & TypeFlags.Union) {
// 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.
let unionType = <UnionType>types[i];
return getUnionType(map((<UnionType>type).types, t => getIntersectionType(replaceElement(types, i, t))),
/*subtypeReduction*/ false, aliasSymbol, aliasTypeArguments);
}
}
const typeSet = [] as TypeSet;
addTypesToIntersection(typeSet, types);
if (typeSet.containsAny) {

View File

@@ -532,6 +532,12 @@ namespace ts {
: undefined;
}
export function replaceElement<T>(array: T[], index: number, value: T): T[] {
const result = array.slice(0);
result[index] = value;
return result;
}
/**
* Performs a binary search, finding the index at which 'value' occurs in 'array'.
* If no such index is found, returns the 2's-complement of first index at which