Merge pull request #13905 from Microsoft/optionalParametersInJSFunctions

Treat function paramters in a .js file with no JSDoc as optional
This commit is contained in:
Mohamed Hegazy 2017-02-09 16:46:19 -08:00 committed by GitHub
commit 2fc634f460
7 changed files with 120 additions and 1 deletions

View file

@ -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;
}

View file

@ -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) {

View file

@ -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))

View file

@ -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

View file

@ -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

View file

@ -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);

View file

@ -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