diff --git a/src/compiler/checker.ts b/src/compiler/checker.ts index 2411cce31b..ac1135788c 100644 --- a/src/compiler/checker.ts +++ b/src/compiler/checker.ts @@ -5241,6 +5241,7 @@ namespace ts { let hasThisParameter: boolean; const iife = getImmediatelyInvokedFunctionExpression(declaration); const isJSConstructSignature = isJSDocConstructSignature(declaration); + const isUntypedSignatureInJSFile = !iife && !isJSConstructSignature && isInJavaScriptFile(declaration) && !hasJSDocParameterTags(declaration); // If this is a JSDoc construct signature, then skip the first parameter in the // parameter list. The first parameter represents the return type of the construct @@ -5269,7 +5270,8 @@ namespace ts { // 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); + isJSDocOptionalParameter(param) || + isUntypedSignatureInJSFile; if (!isOptionalParameter) { minArgumentCount = parameters.length; } diff --git a/src/compiler/utilities.ts b/src/compiler/utilities.ts index 91cd6a89b8..39d53a9a9c 100644 --- a/src/compiler/utilities.ts +++ b/src/compiler/utilities.ts @@ -1518,6 +1518,11 @@ namespace ts { return map(getJSDocs(node), doc => doc.comment); } + export function hasJSDocParameterTags(node: FunctionLikeDeclaration | SignatureDeclaration) { + const parameterTags = getJSDocTags(node, SyntaxKind.JSDocParameterTag); + return parameterTags && parameterTags.length > 0; + } + function getJSDocTags(node: Node, kind: SyntaxKind): JSDocTag[] { const docs = getJSDocs(node); if (docs) { diff --git a/tests/baselines/reference/jsFileFunctionParametersAsOptional.symbols b/tests/baselines/reference/jsFileFunctionParametersAsOptional.symbols new file mode 100644 index 0000000000..040b910f37 --- /dev/null +++ b/tests/baselines/reference/jsFileFunctionParametersAsOptional.symbols @@ -0,0 +1,22 @@ +=== tests/cases/compiler/foo.js === + +function f(a, b, c) { } +>f : Symbol(f, Decl(foo.js, 0, 0)) +>a : Symbol(a, Decl(foo.js, 1, 11)) +>b : Symbol(b, Decl(foo.js, 1, 13)) +>c : Symbol(c, Decl(foo.js, 1, 16)) + + +=== tests/cases/compiler/bar.ts === +f(); +>f : Symbol(f, Decl(foo.js, 0, 0)) + +f(1); +>f : Symbol(f, Decl(foo.js, 0, 0)) + +f(1, 2); +>f : Symbol(f, Decl(foo.js, 0, 0)) + +f(1, 2, 3); +>f : Symbol(f, Decl(foo.js, 0, 0)) + diff --git a/tests/baselines/reference/jsFileFunctionParametersAsOptional.types b/tests/baselines/reference/jsFileFunctionParametersAsOptional.types new file mode 100644 index 0000000000..d6d8f9b04a --- /dev/null +++ b/tests/baselines/reference/jsFileFunctionParametersAsOptional.types @@ -0,0 +1,32 @@ +=== tests/cases/compiler/foo.js === + +function f(a, b, c) { } +>f : (a: any, b: any, c: any) => void +>a : any +>b : any +>c : any + + +=== tests/cases/compiler/bar.ts === +f(); +>f() : void +>f : (a: any, b: any, c: any) => void + +f(1); +>f(1) : void +>f : (a: any, b: any, c: any) => void +>1 : 1 + +f(1, 2); +>f(1, 2) : void +>f : (a: any, b: any, c: any) => void +>1 : 1 +>2 : 2 + +f(1, 2, 3); +>f(1, 2, 3) : void +>f : (a: any, b: any, c: any) => void +>1 : 1 +>2 : 2 +>3 : 3 + diff --git a/tests/baselines/reference/jsFileFunctionParametersAsOptional2.errors.txt b/tests/baselines/reference/jsFileFunctionParametersAsOptional2.errors.txt new file mode 100644 index 0000000000..26ada935ee --- /dev/null +++ b/tests/baselines/reference/jsFileFunctionParametersAsOptional2.errors.txt @@ -0,0 +1,28 @@ +tests/cases/compiler/bar.ts(1,1): error TS2346: Supplied parameters do not match any signature of call target. +tests/cases/compiler/bar.ts(2,1): error TS2346: Supplied parameters do not match any signature of call target. +tests/cases/compiler/bar.ts(3,1): error TS2346: Supplied parameters do not match any signature of call target. + + +==== tests/cases/compiler/foo.js (0 errors) ==== + + /** + * @param a + * @param b + * @param c + */ + function f(a, b, c) { } + + +==== tests/cases/compiler/bar.ts (3 errors) ==== + f(); // Error + ~~~ +!!! error TS2346: Supplied parameters do not match any signature of call target. + f(1); // Error + ~~~~ +!!! error TS2346: Supplied parameters do not match any signature of call target. + f(1, 2); // Error + ~~~~~~~ +!!! error TS2346: Supplied parameters do not match any signature of call target. + + f(1, 2, 3); // OK + \ No newline at end of file diff --git a/tests/cases/compiler/jsFileFunctionParametersAsOptional.ts b/tests/cases/compiler/jsFileFunctionParametersAsOptional.ts new file mode 100644 index 0000000000..f2673f310b --- /dev/null +++ b/tests/cases/compiler/jsFileFunctionParametersAsOptional.ts @@ -0,0 +1,12 @@ +// @allowJs: true +// @noEmit: true + +// @filename: foo.js +function f(a, b, c) { } + + +// @filename: bar.ts +f(); +f(1); +f(1, 2); +f(1, 2, 3); diff --git a/tests/cases/compiler/jsFileFunctionParametersAsOptional2.ts b/tests/cases/compiler/jsFileFunctionParametersAsOptional2.ts new file mode 100644 index 0000000000..01aebb2971 --- /dev/null +++ b/tests/cases/compiler/jsFileFunctionParametersAsOptional2.ts @@ -0,0 +1,18 @@ +// @allowJs: true +// @noEmit: true + +// @filename: foo.js +/** + * @param a + * @param b + * @param c + */ +function f(a, b, c) { } + + +// @filename: bar.ts +f(); // Error +f(1); // Error +f(1, 2); // Error + +f(1, 2, 3); // OK