Skip to content

Commit a163641

Browse files
committed
isAritySmaller runs later: getNonGenericSignature
1 parent 2c09574 commit a163641

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
@@ -10299,16 +10299,32 @@ namespace ts {
1029910299

1030010300
// If the given type is an object or union type, if that type has a single signature, and if
1030110301
// 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 {
1030310303
const signatures = getSignaturesOfStructuredType(type, SignatureKind.Call);
1030410304
if (signatures.length === 1) {
1030510305
const signature = signatures[0];
10306-
if (!signature.typeParameters) {
10306+
if (!signature.typeParameters && !isAritySmaller(signature, node)) {
1030710307
return signature;
1030810308
}
1030910309
}
1031010310
}
1031110311

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+
1031210328
function isFunctionExpressionOrArrowFunction(node: Node): node is FunctionExpression | ArrowFunction {
1031310329
return node.kind === SyntaxKind.FunctionExpression || node.kind === SyntaxKind.ArrowFunction;
1031410330
}
@@ -10337,17 +10353,13 @@ namespace ts {
1033710353
if (!type) {
1033810354
return undefined;
1033910355
}
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-
}
1034410356
if (!(type.flags & TypeFlags.Union)) {
10345-
return getNonGenericSignature(type);
10357+
return getNonGenericSignature(type, node);
1034610358
}
1034710359
let signatureList: Signature[];
1034810360
const types = (<UnionType>type).types;
1034910361
for (const current of types) {
10350-
const signature = getNonGenericSignature(current);
10362+
const signature = getNonGenericSignature(current, node);
1035110363
if (signature) {
1035210364
if (!signatureList) {
1035310365
// This signature will contribute to contextual union signature
@@ -10375,26 +10387,6 @@ namespace ts {
1037510387
return result;
1037610388
}
1037710389

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-
1039810390
/**
1039910391
* Detect if the mapper implies an inference context. Specifically, there are 4 possible values
1040010392
* for a mapper. Let's go through each one of them:

0 commit comments

Comments
 (0)