Skip to content

Commit 1796826

Browse files
committed
isAritySmaller runs later: getNonGenericSignature
1 parent 278d0a4 commit 1796826

File tree

1 file changed

+20
-28
lines changed

1 file changed

+20
-28
lines changed

src/compiler/checker.ts

Lines changed: 20 additions & 28 deletions
Original file line numberDiff line numberDiff line change
@@ -10305,16 +10305,32 @@ namespace ts {
1030510305

1030610306
// If the given type is an object or union type, if that type has a single signature, and if
1030710307
// that signature is non-generic, return the signature. Otherwise return undefined.
10308-
function getNonGenericSignature(type: Type): Signature {
10308+
function getNonGenericSignature(type: Type, node: FunctionExpression | ArrowFunction | MethodDeclaration): Signature {
1030910309
const signatures = getSignaturesOfStructuredType(type, SignatureKind.Call);
1031010310
if (signatures.length === 1) {
1031110311
const signature = signatures[0];
10312-
if (!signature.typeParameters) {
10312+
if (!signature.typeParameters && !isAritySmaller(signature, node)) {
1031310313
return signature;
1031410314
}
1031510315
}
1031610316
}
1031710317

10318+
/** If the contextual signature has fewer parameters than the function expression, do not use it */
10319+
function isAritySmaller(signature: Signature, target: FunctionExpression | ArrowFunction | MethodDeclaration) {
10320+
let targetParameterCount = 0;
10321+
for (; targetParameterCount < target.parameters.length; targetParameterCount++) {
10322+
const param = target.parameters[targetParameterCount];
10323+
if (param.initializer || param.questionToken || param.dotDotDotToken || isJSDocOptionalParameter(param)) {
10324+
break;
10325+
}
10326+
}
10327+
if (target.parameters.length && parameterIsThisKeyword(target.parameters[0])) {
10328+
targetParameterCount--;
10329+
}
10330+
const sourceLength = signature.hasRestParameter ? Number.MAX_VALUE : signature.parameters.length;
10331+
return sourceLength < targetParameterCount;
10332+
}
10333+
1031810334
function isFunctionExpressionOrArrowFunction(node: Node): node is FunctionExpression | ArrowFunction {
1031910335
return node.kind === SyntaxKind.FunctionExpression || node.kind === SyntaxKind.ArrowFunction;
1032010336
}
@@ -10343,17 +10359,13 @@ namespace ts {
1034310359
if (!type) {
1034410360
return undefined;
1034510361
}
10346-
// If the contextual signature has fewer parameters than the function expression, do not use it
10347-
if (isFunctionExpressionOrArrowFunction(node) && isAritySmaller(type, node)) {
10348-
return undefined;
10349-
}
1035010362
if (!(type.flags & TypeFlags.Union)) {
10351-
return getNonGenericSignature(type);
10363+
return getNonGenericSignature(type, node);
1035210364
}
1035310365
let signatureList: Signature[];
1035410366
const types = (<UnionType>type).types;
1035510367
for (const current of types) {
10356-
const signature = getNonGenericSignature(current);
10368+
const signature = getNonGenericSignature(current, node);
1035710369
if (signature) {
1035810370
if (!signatureList) {
1035910371
// This signature will contribute to contextual union signature
@@ -10381,26 +10393,6 @@ namespace ts {
1038110393
return result;
1038210394
}
1038310395

10384-
function isAritySmaller(sourceType: Type, target: FunctionExpression | ArrowFunction) {
10385-
if (isFunctionType(sourceType)) {
10386-
let targetParameterCount = 0;
10387-
for (; targetParameterCount < target.parameters.length; targetParameterCount++) {
10388-
const param = target.parameters[targetParameterCount];
10389-
if (param.initializer || param.questionToken || param.dotDotDotToken || isJSDocOptionalParameter(param)) {
10390-
break;
10391-
}
10392-
}
10393-
if (target.parameters.length && parameterIsThisKeyword(target.parameters[0])) {
10394-
targetParameterCount--;
10395-
}
10396-
const sourceSignatures = getSignaturesOfType(sourceType, SignatureKind.Call);
10397-
const sourceLengths = sourceSignatures.map(sig => !sig.hasRestParameter ? sig.parameters.length : Number.MAX_VALUE);
10398-
return forEach(sourceLengths, len => len < targetParameterCount);
10399-
}
10400-
10401-
return false;
10402-
}
10403-
1040410396
/**
1040510397
* Detect if the mapper implies an inference context. Specifically, there are 4 possible values
1040610398
* for a mapper. Let's go through each one of them:

0 commit comments

Comments
 (0)