@@ -27,6 +27,8 @@ namespace ts {
27
27
return symbol.id;
28
28
}
29
29
30
+ declare let gTypeToString: (type: Type) => string;
31
+
30
32
export function createTypeChecker(host: TypeCheckerHost, produceDiagnostics: boolean): TypeChecker {
31
33
// Cancellation that controls whether or not we can cancel in the middle of type checking.
32
34
// In general cancelling is *not* safe for the type checker. We might be in the middle of
@@ -45,6 +47,8 @@ namespace ts {
45
47
const Type = objectAllocator.getTypeConstructor();
46
48
const Signature = objectAllocator.getSignatureConstructor();
47
49
50
+ gTypeToString = typeToString;
51
+
48
52
let typeCount = 0;
49
53
let symbolCount = 0;
50
54
@@ -6437,6 +6441,10 @@ namespace ts {
6437
6441
return context.mapper;
6438
6442
}
6439
6443
6444
+ function identity<T>(x: T): T {
6445
+ return x;
6446
+ }
6447
+
6440
6448
function identityMapper(type: Type): Type {
6441
6449
return type;
6442
6450
}
@@ -6487,10 +6495,22 @@ namespace ts {
6487
6495
if (signature.typePredicate) {
6488
6496
freshTypePredicate = cloneTypePredicate(signature.typePredicate, mapper);
6489
6497
}
6498
+ const returnType = instantiateType(signature.resolvedReturnType, mapper);
6499
+ const callSignature = returnType && getSingleCallSignature(returnType);
6500
+ if (callSignature && !callSignature.typeParameters && hasFreeTypeVars(callSignature)) {
6501
+ // this is an inferred signature
6502
+ const paramTypes = map(callSignature.parameters, getTypeOfSymbol);
6503
+ if (!contains(paramTypes, callSignature.resolvedReturnType)) {
6504
+ paramTypes.push(callSignature.resolvedReturnType);
6505
+ }
6506
+ const typeParams = <TypeParameter[]>filter(paramTypes, type => !!(type.flags & TypeFlags.TypeParameter));
6507
+ Debug.assert(!!typeParams.length);
6508
+ callSignature.typeParameters = typeParams;
6509
+ }
6490
6510
const result = createSignature(signature.declaration, freshTypeParameters,
6491
6511
signature.thisParameter && instantiateSymbol(signature.thisParameter, mapper),
6492
6512
instantiateList(signature.parameters, mapper, instantiateSymbol),
6493
- instantiateType(signature.resolvedReturnType, mapper) ,
6513
+ returnType ,
6494
6514
freshTypePredicate,
6495
6515
signature.minArgumentCount, signature.hasRestParameter, signature.hasLiteralTypes);
6496
6516
result.target = signature;
@@ -8750,7 +8770,14 @@ namespace ts {
8750
8770
const targetLen = targetSignatures.length;
8751
8771
const len = sourceLen < targetLen ? sourceLen : targetLen;
8752
8772
for (let i = 0; i < len; i++) {
8753
- inferFromSignature(getErasedSignature(sourceSignatures[sourceLen - len + i]), getErasedSignature(targetSignatures[targetLen - len + i]));
8773
+ const sourceSignature = sourceSignatures[sourceLen - len + i];
8774
+ const targetSignature = targetSignatures[targetLen - len + i];
8775
+
8776
+ const mapper = isPolymorphicSignature(sourceSignature) && isPolymorphicSignature(targetSignature)
8777
+ ? identity
8778
+ : getErasedSignature;
8779
+
8780
+ inferFromSignature(mapper(sourceSignature), mapper(targetSignature));
8754
8781
}
8755
8782
}
8756
8783
@@ -15043,7 +15070,7 @@ namespace ts {
15043
15070
const contextualType = getApparentTypeOfContextualType(<Expression>node);
15044
15071
if (contextualType) {
15045
15072
const contextualSignature = getSingleCallSignature(contextualType);
15046
- if (contextualSignature && !contextualSignature.typeParameters ) {
15073
+ if (contextualSignature && !isPolymorphicSignature( contextualSignature) ) {
15047
15074
return getOrCreateTypeFromSignature(instantiateSignatureInContextOf(signature, contextualSignature, contextualMapper));
15048
15075
}
15049
15076
}
@@ -15053,6 +15080,15 @@ namespace ts {
15053
15080
return type;
15054
15081
}
15055
15082
15083
+ function isPolymorphicSignature(signature: Signature | undefined) {
15084
+ return signature && (signature.typeParameters || hasFreeTypeVars(signature));
15085
+ }
15086
+
15087
+ function hasFreeTypeVars(signature: Signature) {
15088
+ return signature.resolvedReturnType && signature.resolvedReturnType.flags & TypeFlags.TypeParameter
15089
+ || forEach(signature.parameters, (symb) => getTypeOfSymbol(symb).flags & TypeFlags.TypeParameter);
15090
+ }
15091
+
15056
15092
// Returns the type of an expression. Unlike checkExpression, this function is simply concerned
15057
15093
// with computing the type and may not fully check all contained sub-expressions for errors.
15058
15094
function getTypeOfExpression(node: Expression) {
0 commit comments