@@ -10299,16 +10299,32 @@ namespace ts {
10299
10299
10300
10300
// If the given type is an object or union type, if that type has a single signature, and if
10301
10301
// that signature is non-generic, return the signature. Otherwise return undefined.
10302
- function getNonGenericSignature(type: Type): Signature {
10302
+ function getNonGenericSignature(type: Type, node: FunctionExpression | ArrowFunction | MethodDeclaration ): Signature {
10303
10303
const signatures = getSignaturesOfStructuredType(type, SignatureKind.Call);
10304
10304
if (signatures.length === 1) {
10305
10305
const signature = signatures[0];
10306
- if (!signature.typeParameters) {
10306
+ if (!signature.typeParameters && !isAritySmaller(signature, node) ) {
10307
10307
return signature;
10308
10308
}
10309
10309
}
10310
10310
}
10311
10311
10312
+ /** If the contextual signature has fewer parameters than the function expression, do not use it */
10313
+ function isAritySmaller(signature: Signature, target: FunctionExpression | ArrowFunction | MethodDeclaration) {
10314
+ let targetParameterCount = 0;
10315
+ for (; targetParameterCount < target.parameters.length; targetParameterCount++) {
10316
+ const param = target.parameters[targetParameterCount];
10317
+ if (param.initializer || param.questionToken || param.dotDotDotToken || isJSDocOptionalParameter(param)) {
10318
+ break;
10319
+ }
10320
+ }
10321
+ if (target.parameters.length && parameterIsThisKeyword(target.parameters[0])) {
10322
+ targetParameterCount--;
10323
+ }
10324
+ const sourceLength = signature.hasRestParameter ? Number.MAX_VALUE : signature.parameters.length;
10325
+ return sourceLength < targetParameterCount;
10326
+ }
10327
+
10312
10328
function isFunctionExpressionOrArrowFunction(node: Node): node is FunctionExpression | ArrowFunction {
10313
10329
return node.kind === SyntaxKind.FunctionExpression || node.kind === SyntaxKind.ArrowFunction;
10314
10330
}
@@ -10337,17 +10353,13 @@ namespace ts {
10337
10353
if (!type) {
10338
10354
return undefined;
10339
10355
}
10340
- // If the contextual signature has fewer parameters than the function expression, do not use it
10341
- if (isFunctionExpressionOrArrowFunction(node) && isAritySmaller(type, node)) {
10342
- return undefined;
10343
- }
10344
10356
if (!(type.flags & TypeFlags.Union)) {
10345
- return getNonGenericSignature(type);
10357
+ return getNonGenericSignature(type, node );
10346
10358
}
10347
10359
let signatureList: Signature[];
10348
10360
const types = (<UnionType>type).types;
10349
10361
for (const current of types) {
10350
- const signature = getNonGenericSignature(current);
10362
+ const signature = getNonGenericSignature(current, node );
10351
10363
if (signature) {
10352
10364
if (!signatureList) {
10353
10365
// This signature will contribute to contextual union signature
@@ -10375,26 +10387,6 @@ namespace ts {
10375
10387
return result;
10376
10388
}
10377
10389
10378
- function isAritySmaller(sourceType: Type, target: FunctionExpression | ArrowFunction) {
10379
- if (isFunctionType(sourceType)) {
10380
- let targetParameterCount = 0;
10381
- for (; targetParameterCount < target.parameters.length; targetParameterCount++) {
10382
- const param = target.parameters[targetParameterCount];
10383
- if (param.initializer || param.questionToken || param.dotDotDotToken || isJSDocOptionalParameter(param)) {
10384
- break;
10385
- }
10386
- }
10387
- if (target.parameters.length && parameterIsThisKeyword(target.parameters[0])) {
10388
- targetParameterCount--;
10389
- }
10390
- const sourceSignatures = getSignaturesOfType(sourceType, SignatureKind.Call);
10391
- const sourceLengths = sourceSignatures.map(sig => !sig.hasRestParameter ? sig.parameters.length : Number.MAX_VALUE);
10392
- return forEach(sourceLengths, len => len < targetParameterCount);
10393
- }
10394
-
10395
- return false;
10396
- }
10397
-
10398
10390
/**
10399
10391
* Detect if the mapper implies an inference context. Specifically, there are 4 possible values
10400
10392
* for a mapper. Let's go through each one of them:
0 commit comments