Exclude undefined/null from flags propagation within union types

This commit is contained in:
Anders Hejlsberg 2016-02-15 19:26:20 -08:00
parent 41401c7cae
commit 586c3ac86f

View File

@ -4387,10 +4387,12 @@ namespace ts {
// It is only necessary to do so if a constituent type might be the undefined type, the null type, the type
// of an object literal or the anyFunctionType. This is because there are operations in the type checker
// that care about the presence of such types at arbitrary depth in a containing type.
function getPropagatingFlagsOfTypes(types: Type[]): TypeFlags {
function getPropagatingFlagsOfTypes(types: Type[], excludeKinds: TypeFlags): TypeFlags {
let result: TypeFlags = 0;
for (const type of types) {
result |= type.flags;
if (!(type.flags & excludeKinds)) {
result |= type.flags;
}
}
return result & TypeFlags.PropagatingFlags;
}
@ -4399,7 +4401,8 @@ namespace ts {
const id = getTypeListId(typeArguments);
let type = target.instantiations[id];
if (!type) {
const flags = TypeFlags.Reference | (typeArguments ? getPropagatingFlagsOfTypes(typeArguments) : 0);
const propagatedFlags = typeArguments ? getPropagatingFlagsOfTypes(typeArguments, /*excludeKinds*/ 0) : 0;
const flags = TypeFlags.Reference | propagatedFlags;
type = target.instantiations[id] = <TypeReference>createObjectType(flags, target.symbol);
type.target = target;
type.typeArguments = typeArguments;
@ -4659,7 +4662,8 @@ namespace ts {
}
function createNewTupleType(elementTypes: Type[]) {
const type = <TupleType>createObjectType(TypeFlags.Tuple | getPropagatingFlagsOfTypes(elementTypes));
const propagatedFlags = getPropagatingFlagsOfTypes(elementTypes, /*excludeKinds*/ 0);
const type = <TupleType>createObjectType(TypeFlags.Tuple | propagatedFlags);
type.elementTypes = elementTypes;
return type;
}
@ -4766,7 +4770,8 @@ namespace ts {
const id = getTypeListId(typeSet);
let type = unionTypes[id];
if (!type) {
type = unionTypes[id] = <UnionType>createObjectType(TypeFlags.Union | getPropagatingFlagsOfTypes(typeSet));
const propagatedFlags = getPropagatingFlagsOfTypes(typeSet, /*excludeKinds*/ TypeFlags.Undefined);
type = unionTypes[id] = <UnionType>createObjectType(TypeFlags.Union | propagatedFlags);
type.types = typeSet;
}
return type;
@ -4800,7 +4805,8 @@ namespace ts {
const id = getTypeListId(typeSet);
let type = intersectionTypes[id];
if (!type) {
type = intersectionTypes[id] = <IntersectionType>createObjectType(TypeFlags.Intersection | getPropagatingFlagsOfTypes(typeSet));
const propagatedFlags = getPropagatingFlagsOfTypes(typeSet, /*excludeKinds*/ TypeFlags.Undefined);
type = intersectionTypes[id] = <IntersectionType>createObjectType(TypeFlags.Intersection | propagatedFlags);
type.types = typeSet;
}
return type;