@@ -10305,16 +10305,32 @@ namespace ts {
10305
10305
10306
10306
// If the given type is an object or union type, if that type has a single signature, and if
10307
10307
// 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 {
10309
10309
const signatures = getSignaturesOfStructuredType(type, SignatureKind.Call);
10310
10310
if (signatures.length === 1) {
10311
10311
const signature = signatures[0];
10312
- if (!signature.typeParameters) {
10312
+ if (!signature.typeParameters && !isAritySmaller(signature, node) ) {
10313
10313
return signature;
10314
10314
}
10315
10315
}
10316
10316
}
10317
10317
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
+
10318
10334
function isFunctionExpressionOrArrowFunction(node: Node): node is FunctionExpression | ArrowFunction {
10319
10335
return node.kind === SyntaxKind.FunctionExpression || node.kind === SyntaxKind.ArrowFunction;
10320
10336
}
@@ -10343,17 +10359,13 @@ namespace ts {
10343
10359
if (!type) {
10344
10360
return undefined;
10345
10361
}
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
- }
10350
10362
if (!(type.flags & TypeFlags.Union)) {
10351
- return getNonGenericSignature(type);
10363
+ return getNonGenericSignature(type, node );
10352
10364
}
10353
10365
let signatureList: Signature[];
10354
10366
const types = (<UnionType>type).types;
10355
10367
for (const current of types) {
10356
- const signature = getNonGenericSignature(current);
10368
+ const signature = getNonGenericSignature(current, node );
10357
10369
if (signature) {
10358
10370
if (!signatureList) {
10359
10371
// This signature will contribute to contextual union signature
@@ -10381,26 +10393,6 @@ namespace ts {
10381
10393
return result;
10382
10394
}
10383
10395
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
-
10404
10396
/**
10405
10397
* Detect if the mapper implies an inference context. Specifically, there are 4 possible values
10406
10398
* for a mapper. Let's go through each one of them:
0 commit comments