Instantiate type parameter constraints with type parameter as 'this'

This commit is contained in:
Anders Hejlsberg
2015-11-06 08:54:22 -08:00
parent 9b4956fa11
commit eee211a2a6
2 changed files with 19 additions and 7 deletions

View File

@@ -2990,7 +2990,7 @@ namespace ts {
(<GenericType>type).typeArguments = type.typeParameters;
type.thisType = <TypeParameter>createType(TypeFlags.TypeParameter | TypeFlags.ThisType);
type.thisType.symbol = symbol;
type.thisType.constraint = getTypeWithThisArgument(type);
type.thisType.constraint = type;
}
}
return <InterfaceType>links.declaredType;
@@ -3533,6 +3533,21 @@ namespace ts {
return type.flags & TypeFlags.UnionOrIntersection ? getPropertiesOfUnionOrIntersectionType(<UnionType>type) : getPropertiesOfObjectType(type);
}
/**
* The apparent type of a type parameter is the base constraint instantiated with the type parameter
* as the type argument for the 'this' type.
*/
function getApparentTypeOfTypeParameter(type: TypeParameter) {
if (!type.resolvedApparentType) {
let constraintType = getConstraintOfTypeParameter(type);
while (constraintType && constraintType.flags & TypeFlags.TypeParameter) {
constraintType = getConstraintOfTypeParameter(<TypeParameter>constraintType);
}
type.resolvedApparentType = getTypeWithThisArgument(constraintType || emptyObjectType, type);
}
return type.resolvedApparentType;
}
/**
* For a type parameter, return the base constraint of the type parameter. For the string, number,
* boolean, and symbol primitive types, return the corresponding object types. Otherwise return the
@@ -3540,12 +3555,7 @@ namespace ts {
*/
function getApparentType(type: Type): Type {
if (type.flags & TypeFlags.TypeParameter) {
do {
type = getConstraintOfTypeParameter(<TypeParameter>type);
} while (type && type.flags & TypeFlags.TypeParameter);
if (!type) {
type = emptyObjectType;
}
type = getApparentTypeOfTypeParameter(<TypeParameter>type);
}
if (type.flags & TypeFlags.StringLike) {
type = globalStringType;

View File

@@ -1956,6 +1956,8 @@ namespace ts {
target?: TypeParameter; // Instantiation target
/* @internal */
mapper?: TypeMapper; // Instantiation mapper
/* @internal */
resolvedApparentType: Type;
}
export const enum SignatureKind {