diff --git a/src/compiler/checker.ts b/src/compiler/checker.ts index ab50ca652d..9393b7b6d1 100644 --- a/src/compiler/checker.ts +++ b/src/compiler/checker.ts @@ -4401,7 +4401,7 @@ namespace ts { return result; } - function isOptionalParameter(node: ParameterDeclaration) { + function isJSDocOptionalParameter(node: ParameterDeclaration) { if (node.flags & NodeFlags.JavaScriptFile) { if (node.type && node.type.kind === SyntaxKind.JSDocOptionalType) { return true; @@ -4418,8 +4418,10 @@ namespace ts { } } } + } - if (hasQuestionToken(node)) { + function isOptionalParameter(node: ParameterDeclaration) { + if (hasQuestionToken(node) || isJSDocOptionalParameter(node)) { return true; } @@ -4486,7 +4488,7 @@ namespace ts { hasStringLiterals = true; } - if (param.initializer || param.questionToken || param.dotDotDotToken) { + if (param.initializer || param.questionToken || param.dotDotDotToken || isJSDocOptionalParameter(param)) { if (minArgumentCount < 0) { minArgumentCount = i - (hasThisParameter ? 1 : 0); } diff --git a/tests/baselines/reference/signaturesUseJSDocForOptionalParameters.js b/tests/baselines/reference/signaturesUseJSDocForOptionalParameters.js new file mode 100644 index 0000000000..b3d61a9f59 --- /dev/null +++ b/tests/baselines/reference/signaturesUseJSDocForOptionalParameters.js @@ -0,0 +1,32 @@ +//// [jsDocOptionality.js] +function MyClass() { + this.prop = null; +} +/** + * @param {string} required + * @param {string} [notRequired] + * @returns {MyClass} + */ +MyClass.prototype.optionalParam = function(required, notRequired) { + return this; +}; +let pInst = new MyClass(); +let c1 = pInst.optionalParam('hello') +let c2 = pInst.optionalParam('hello', null) + + +//// [out_1.js] +function MyClass() { + this.prop = null; +} +/** + * @param {string} required + * @param {string} [notRequired] + * @returns {MyClass} + */ +MyClass.prototype.optionalParam = function (required, notRequired) { + return this; +}; +var pInst = new MyClass(); +var c1 = pInst.optionalParam('hello'); +var c2 = pInst.optionalParam('hello', null); diff --git a/tests/baselines/reference/signaturesUseJSDocForOptionalParameters.symbols b/tests/baselines/reference/signaturesUseJSDocForOptionalParameters.symbols new file mode 100644 index 0000000000..5ea2756598 --- /dev/null +++ b/tests/baselines/reference/signaturesUseJSDocForOptionalParameters.symbols @@ -0,0 +1,38 @@ +=== tests/cases/compiler/jsDocOptionality.js === +function MyClass() { +>MyClass : Symbol(MyClass, Decl(jsDocOptionality.js, 0, 0)) + + this.prop = null; +>prop : Symbol(MyClass.prop, Decl(jsDocOptionality.js, 0, 20)) +} +/** + * @param {string} required + * @param {string} [notRequired] + * @returns {MyClass} + */ +MyClass.prototype.optionalParam = function(required, notRequired) { +>MyClass.prototype : Symbol(MyClass.optionalParam, Decl(jsDocOptionality.js, 2, 1)) +>MyClass : Symbol(MyClass, Decl(jsDocOptionality.js, 0, 0)) +>prototype : Symbol(Function.prototype, Decl(lib.d.ts, --, --)) +>optionalParam : Symbol(MyClass.optionalParam, Decl(jsDocOptionality.js, 2, 1)) +>required : Symbol(required, Decl(jsDocOptionality.js, 8, 43)) +>notRequired : Symbol(notRequired, Decl(jsDocOptionality.js, 8, 52)) + + return this; +}; +let pInst = new MyClass(); +>pInst : Symbol(pInst, Decl(jsDocOptionality.js, 11, 3)) +>MyClass : Symbol(MyClass, Decl(jsDocOptionality.js, 0, 0)) + +let c1 = pInst.optionalParam('hello') +>c1 : Symbol(c1, Decl(jsDocOptionality.js, 12, 3)) +>pInst.optionalParam : Symbol(MyClass.optionalParam, Decl(jsDocOptionality.js, 2, 1)) +>pInst : Symbol(pInst, Decl(jsDocOptionality.js, 11, 3)) +>optionalParam : Symbol(MyClass.optionalParam, Decl(jsDocOptionality.js, 2, 1)) + +let c2 = pInst.optionalParam('hello', null) +>c2 : Symbol(c2, Decl(jsDocOptionality.js, 13, 3)) +>pInst.optionalParam : Symbol(MyClass.optionalParam, Decl(jsDocOptionality.js, 2, 1)) +>pInst : Symbol(pInst, Decl(jsDocOptionality.js, 11, 3)) +>optionalParam : Symbol(MyClass.optionalParam, Decl(jsDocOptionality.js, 2, 1)) + diff --git a/tests/baselines/reference/signaturesUseJSDocForOptionalParameters.types b/tests/baselines/reference/signaturesUseJSDocForOptionalParameters.types new file mode 100644 index 0000000000..2dcaa37b94 --- /dev/null +++ b/tests/baselines/reference/signaturesUseJSDocForOptionalParameters.types @@ -0,0 +1,53 @@ +=== tests/cases/compiler/jsDocOptionality.js === +function MyClass() { +>MyClass : () => void + + this.prop = null; +>this.prop = null : null +>this.prop : any +>this : any +>prop : any +>null : null +} +/** + * @param {string} required + * @param {string} [notRequired] + * @returns {MyClass} + */ +MyClass.prototype.optionalParam = function(required, notRequired) { +>MyClass.prototype.optionalParam = function(required, notRequired) { return this;} : (required: string, notRequired?: string) => { prop: null; optionalParam: any; } +>MyClass.prototype.optionalParam : any +>MyClass.prototype : any +>MyClass : () => void +>prototype : any +>optionalParam : any +>function(required, notRequired) { return this;} : (required: string, notRequired?: string) => { prop: null; optionalParam: any; } +>required : string +>notRequired : string + + return this; +>this : { prop: null; optionalParam: (required: string, notRequired?: string) => { prop: null; optionalParam: any; }; } + +}; +let pInst = new MyClass(); +>pInst : { prop: null; optionalParam: (required: string, notRequired?: string) => { prop: null; optionalParam: any; }; } +>new MyClass() : { prop: null; optionalParam: (required: string, notRequired?: string) => { prop: null; optionalParam: any; }; } +>MyClass : () => void + +let c1 = pInst.optionalParam('hello') +>c1 : { prop: null; optionalParam: (required: string, notRequired?: string) => { prop: null; optionalParam: any; }; } +>pInst.optionalParam('hello') : { prop: null; optionalParam: (required: string, notRequired?: string) => { prop: null; optionalParam: any; }; } +>pInst.optionalParam : (required: string, notRequired?: string) => { prop: null; optionalParam: any; } +>pInst : { prop: null; optionalParam: (required: string, notRequired?: string) => { prop: null; optionalParam: any; }; } +>optionalParam : (required: string, notRequired?: string) => { prop: null; optionalParam: any; } +>'hello' : string + +let c2 = pInst.optionalParam('hello', null) +>c2 : { prop: null; optionalParam: (required: string, notRequired?: string) => { prop: null; optionalParam: any; }; } +>pInst.optionalParam('hello', null) : { prop: null; optionalParam: (required: string, notRequired?: string) => { prop: null; optionalParam: any; }; } +>pInst.optionalParam : (required: string, notRequired?: string) => { prop: null; optionalParam: any; } +>pInst : { prop: null; optionalParam: (required: string, notRequired?: string) => { prop: null; optionalParam: any; }; } +>optionalParam : (required: string, notRequired?: string) => { prop: null; optionalParam: any; } +>'hello' : string +>null : null + diff --git a/tests/cases/compiler/signaturesUseJSDocForOptionalParameters.ts b/tests/cases/compiler/signaturesUseJSDocForOptionalParameters.ts new file mode 100644 index 0000000000..a6f9c9fb39 --- /dev/null +++ b/tests/cases/compiler/signaturesUseJSDocForOptionalParameters.ts @@ -0,0 +1,17 @@ +// @allowJs: true +// @out: out_1.js +// @filename: jsDocOptionality.js +function MyClass() { + this.prop = null; +} +/** + * @param {string} required + * @param {string} [notRequired] + * @returns {MyClass} + */ +MyClass.prototype.optionalParam = function(required, notRequired) { + return this; +}; +let pInst = new MyClass(); +let c1 = pInst.optionalParam('hello') +let c2 = pInst.optionalParam('hello', null)