Skip to content

Commit 73526cf

Browse files
Do some caching so that we don't repeat the same work for the implementation signature for every overload.
1 parent a236461 commit 73526cf

File tree

2 files changed

+19
-4
lines changed

2 files changed

+19
-4
lines changed

src/compiler/checker.ts

Lines changed: 17 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -4115,6 +4115,16 @@ namespace ts {
41154115
return signature.erasedSignatureCache;
41164116
}
41174117

4118+
function getAnyReturningErasedSignature(signature: Signature): Signature {
4119+
if (!signature.anyReturningErasedSignatureCache) {
4120+
const erasedSignature = getErasedSignature(signature);
4121+
const anyReturningErasedSignature = cloneSignature(erasedSignature);
4122+
anyReturningErasedSignature.resolvedReturnType = anyType;
4123+
signature.anyReturningErasedSignatureCache = anyReturningErasedSignature;
4124+
}
4125+
return signature.anyReturningErasedSignatureCache;
4126+
}
4127+
41184128
function getOrCreateTypeFromSignature(signature: Signature): ObjectType {
41194129
// There are two ways to declare a construct signature, one is by declaring a class constructor
41204130
// using the constructor keyword, and the other is declaring a bare construct signature in an
@@ -4985,16 +4995,19 @@ namespace ts {
49854995
const erasedSource = getErasedSignature(implementation);
49864996
const erasedTarget = getErasedSignature(overload);
49874997

4998+
// First see if the return types are compatible in either direction.
49884999
const sourceReturnType = getReturnTypeOfSignature(erasedSource);
49895000
const targetReturnType = getReturnTypeOfSignature(erasedTarget);
49905001
if (targetReturnType === voidType
49915002
|| checkTypeRelatedTo(targetReturnType, sourceReturnType, assignableRelation, /*errorNode*/ undefined)
49925003
|| checkTypeRelatedTo(sourceReturnType, targetReturnType, assignableRelation, /*errorNode*/ undefined)) {
4993-
const anyReturningSource = cloneSignature(erasedSource);
4994-
const anyReturningTarget = cloneSignature(erasedTarget);
4995-
anyReturningSource.resolvedReturnType = anyType;
4996-
anyReturningTarget.resolvedReturnType = anyType;
49975004

5005+
// The return types are compatible, so create versions of the signature with 'any' as the return type.
5006+
// We need to do this so that we can check assignability while disregarding the return type.
5007+
const anyReturningSource = getAnyReturningErasedSignature(implementation);
5008+
const anyReturningTarget = getAnyReturningErasedSignature(overload);
5009+
5010+
// Create object types to actually perform relation checks.
49985011
const anyReturningSourceType = getOrCreateTypeFromSignature(anyReturningSource);
49995012
const anyReturningTargetType = getOrCreateTypeFromSignature(anyReturningTarget);
50005013
return checkTypeRelatedTo(anyReturningSourceType, anyReturningTargetType, assignableRelation, /*errorNode*/ undefined);

src/compiler/types.ts

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -2280,6 +2280,8 @@ namespace ts {
22802280
/* @internal */
22812281
erasedSignatureCache?: Signature; // Erased version of signature (deferred)
22822282
/* @internal */
2283+
anyReturningErasedSignatureCache?: Signature; // A version of the erased signature whose type returns 'any'
2284+
/* @internal */
22832285
isolatedSignatureType?: ObjectType; // A manufactured type that just contains the signature for purposes of signature comparison
22842286
}
22852287

0 commit comments

Comments
 (0)