diff --git a/src/compiler/checker.ts b/src/compiler/checker.ts index 879be1c6fbf..61b1911261d 100644 --- a/src/compiler/checker.ts +++ b/src/compiler/checker.ts @@ -5058,9 +5058,10 @@ namespace ts { if (!links.resolvedSignature) { const parameters: Symbol[] = []; let hasLiteralTypes = false; - let minArgumentCount = -1; + let minArgumentCount = 0; let thisParameter: Symbol = undefined; let hasThisParameter: boolean; + const iife = getImmediatelyInvokedFunctionExpression(declaration); const isJSConstructSignature = isJSDocConstructSignature(declaration); // If this is a JSDoc construct signature, then skip the first parameter in the @@ -5087,14 +5088,12 @@ namespace ts { hasLiteralTypes = true; } - if (param.initializer || param.questionToken || param.dotDotDotToken || isJSDocOptionalParameter(param)) { - if (minArgumentCount < 0) { - minArgumentCount = i - (hasThisParameter ? 1 : 0); - } - } - else { - // If we see any required parameters, it means the prior ones were not in fact optional. - minArgumentCount = -1; + // Record a new minimum argument count if this is not an optional parameter + const isOptionalParameter = param.initializer || param.questionToken || param.dotDotDotToken || + iife && parameters.length > iife.arguments.length && !param.type || + isJSDocOptionalParameter(param); + if (!isOptionalParameter) { + minArgumentCount = parameters.length; } } @@ -5109,13 +5108,6 @@ namespace ts { } } - if (minArgumentCount < 0) { - minArgumentCount = declaration.parameters.length - (hasThisParameter ? 1 : 0); - } - if (isJSConstructSignature) { - minArgumentCount--; - } - const classType = declaration.kind === SyntaxKind.Constructor ? getDeclaredTypeOfClassOrInterface(getMergedSymbol((declaration.parent).symbol)) : undefined; @@ -10933,23 +10925,23 @@ namespace ts { const func = parameter.parent; if (isContextSensitiveFunctionOrObjectLiteralMethod(func)) { const iife = getImmediatelyInvokedFunctionExpression(func); - if (iife) { + if (iife && iife.arguments) { const indexOfParameter = indexOf(func.parameters, parameter); - if (iife.arguments && indexOfParameter < iife.arguments.length) { - if (parameter.dotDotDotToken) { - const restTypes: Type[] = []; - for (let i = indexOfParameter; i < iife.arguments.length; i++) { - restTypes.push(getWidenedLiteralType(checkExpression(iife.arguments[i]))); - } - return createArrayType(getUnionType(restTypes)); + if (parameter.dotDotDotToken) { + const restTypes: Type[] = []; + for (let i = indexOfParameter; i < iife.arguments.length; i++) { + restTypes.push(getWidenedLiteralType(checkExpression(iife.arguments[i]))); } - const links = getNodeLinks(iife); - const cached = links.resolvedSignature; - links.resolvedSignature = anySignature; - const type = getWidenedLiteralType(checkExpression(iife.arguments[indexOfParameter])); - links.resolvedSignature = cached; - return type; + return restTypes.length ? createArrayType(getUnionType(restTypes)) : undefined; } + const links = getNodeLinks(iife); + const cached = links.resolvedSignature; + links.resolvedSignature = anySignature; + const type = indexOfParameter < iife.arguments.length ? + getWidenedLiteralType(checkExpression(iife.arguments[indexOfParameter])) : + parameter.initializer ? undefined : undefinedWideningType; + links.resolvedSignature = cached; + return type; } const contextualSignature = getContextualSignature(func); if (contextualSignature) {