Merge branch 'typeguardsByConstructorSigniture' of https://github.com/vvakame/TypeScript into vvakame-typeguardsByConstructorSigniture

This commit is contained in:
Mohamed Hegazy
2015-05-06 12:44:45 -07:00
4 changed files with 713 additions and 9 deletions

View File

@@ -3634,6 +3634,10 @@ module ts {
return type;
}
function getUnionTypeOfSubtypeConstituents(source: UnionType, target: Type): Type {
return getUnionType(filter(source.types, t => isTypeSubtypeOf(t, target)));
}
function getReducedTypeOfUnionType(type: UnionType): Type {
// If union type was created without subtype reduction, perform the deferred reduction now
if (!type.reducedType) {
@@ -5386,17 +5390,35 @@ module ts {
}
// Target type is type of prototype property
let prototypeProperty = getPropertyOfType(rightType, "prototype");
if (!prototypeProperty) {
return type;
if (prototypeProperty) {
let targetType = getTypeOfSymbol(prototypeProperty);
if (targetType !== anyType) {
// Narrow to the target type if it's a subtype of the current type
if (isTypeSubtypeOf(targetType, type)) {
return targetType;
}
// If the current type is a union type, remove all constituents that aren't subtypes of the target.
if (type.flags & TypeFlags.Union) {
return getUnionTypeOfSubtypeConstituents(<UnionType>type, targetType);
}
}
}
let targetType = getTypeOfSymbol(prototypeProperty);
// Narrow to target type if it is a subtype of current type
if (isTypeSubtypeOf(targetType, type)) {
return targetType;
// Target type is type of construct signature
let constructSignatures: Signature[];
if (rightType.flags & TypeFlags.Interface) {
constructSignatures = resolveDeclaredMembers(<InterfaceType>rightType).declaredConstructSignatures;
}
// If current type is a union type, remove all constituents that aren't subtypes of target type
if (type.flags & TypeFlags.Union) {
return getUnionType(filter((<UnionType>type).types, t => isTypeSubtypeOf(t, targetType)));
else if (rightType.flags & TypeFlags.Anonymous) {
constructSignatures = getSignaturesOfType(rightType, SignatureKind.Construct);
}
if (constructSignatures && constructSignatures.length !== 0) {
let instanceType = getUnionType(map(constructSignatures, signature => getReturnTypeOfSignature(getErasedSignature(signature))));
// Pickup type from union types
if (type.flags & TypeFlags.Union) {
return getUnionTypeOfSubtypeConstituents(<UnionType>type, instanceType);
}
return instanceType;
}
return type;
}