Skip to content

Commit 9134ed3

Browse files
authored
Merge pull request #9303 from Microsoft/signatures-use-jsdoc-for-minArgumentCount
Signatures use JSDoc to determine optionality
2 parents 12bfb7e + 3a7396e commit 9134ed3

File tree

5 files changed

+145
-3
lines changed

5 files changed

+145
-3
lines changed

src/compiler/checker.ts

Lines changed: 5 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -4401,7 +4401,7 @@ namespace ts {
44014401
return result;
44024402
}
44034403

4404-
function isOptionalParameter(node: ParameterDeclaration) {
4404+
function isJSDocOptionalParameter(node: ParameterDeclaration) {
44054405
if (node.flags & NodeFlags.JavaScriptFile) {
44064406
if (node.type && node.type.kind === SyntaxKind.JSDocOptionalType) {
44074407
return true;
@@ -4418,8 +4418,10 @@ namespace ts {
44184418
}
44194419
}
44204420
}
4421+
}
44214422

4422-
if (hasQuestionToken(node)) {
4423+
function isOptionalParameter(node: ParameterDeclaration) {
4424+
if (hasQuestionToken(node) || isJSDocOptionalParameter(node)) {
44234425
return true;
44244426
}
44254427

@@ -4486,7 +4488,7 @@ namespace ts {
44864488
hasStringLiterals = true;
44874489
}
44884490

4489-
if (param.initializer || param.questionToken || param.dotDotDotToken) {
4491+
if (param.initializer || param.questionToken || param.dotDotDotToken || isJSDocOptionalParameter(param)) {
44904492
if (minArgumentCount < 0) {
44914493
minArgumentCount = i - (hasThisParameter ? 1 : 0);
44924494
}
Lines changed: 32 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,32 @@
1+
//// [jsDocOptionality.js]
2+
function MyClass() {
3+
this.prop = null;
4+
}
5+
/**
6+
* @param {string} required
7+
* @param {string} [notRequired]
8+
* @returns {MyClass}
9+
*/
10+
MyClass.prototype.optionalParam = function(required, notRequired) {
11+
return this;
12+
};
13+
let pInst = new MyClass();
14+
let c1 = pInst.optionalParam('hello')
15+
let c2 = pInst.optionalParam('hello', null)
16+
17+
18+
//// [out_1.js]
19+
function MyClass() {
20+
this.prop = null;
21+
}
22+
/**
23+
* @param {string} required
24+
* @param {string} [notRequired]
25+
* @returns {MyClass}
26+
*/
27+
MyClass.prototype.optionalParam = function (required, notRequired) {
28+
return this;
29+
};
30+
var pInst = new MyClass();
31+
var c1 = pInst.optionalParam('hello');
32+
var c2 = pInst.optionalParam('hello', null);
Lines changed: 38 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,38 @@
1+
=== tests/cases/compiler/jsDocOptionality.js ===
2+
function MyClass() {
3+
>MyClass : Symbol(MyClass, Decl(jsDocOptionality.js, 0, 0))
4+
5+
this.prop = null;
6+
>prop : Symbol(MyClass.prop, Decl(jsDocOptionality.js, 0, 20))
7+
}
8+
/**
9+
* @param {string} required
10+
* @param {string} [notRequired]
11+
* @returns {MyClass}
12+
*/
13+
MyClass.prototype.optionalParam = function(required, notRequired) {
14+
>MyClass.prototype : Symbol(MyClass.optionalParam, Decl(jsDocOptionality.js, 2, 1))
15+
>MyClass : Symbol(MyClass, Decl(jsDocOptionality.js, 0, 0))
16+
>prototype : Symbol(Function.prototype, Decl(lib.d.ts, --, --))
17+
>optionalParam : Symbol(MyClass.optionalParam, Decl(jsDocOptionality.js, 2, 1))
18+
>required : Symbol(required, Decl(jsDocOptionality.js, 8, 43))
19+
>notRequired : Symbol(notRequired, Decl(jsDocOptionality.js, 8, 52))
20+
21+
return this;
22+
};
23+
let pInst = new MyClass();
24+
>pInst : Symbol(pInst, Decl(jsDocOptionality.js, 11, 3))
25+
>MyClass : Symbol(MyClass, Decl(jsDocOptionality.js, 0, 0))
26+
27+
let c1 = pInst.optionalParam('hello')
28+
>c1 : Symbol(c1, Decl(jsDocOptionality.js, 12, 3))
29+
>pInst.optionalParam : Symbol(MyClass.optionalParam, Decl(jsDocOptionality.js, 2, 1))
30+
>pInst : Symbol(pInst, Decl(jsDocOptionality.js, 11, 3))
31+
>optionalParam : Symbol(MyClass.optionalParam, Decl(jsDocOptionality.js, 2, 1))
32+
33+
let c2 = pInst.optionalParam('hello', null)
34+
>c2 : Symbol(c2, Decl(jsDocOptionality.js, 13, 3))
35+
>pInst.optionalParam : Symbol(MyClass.optionalParam, Decl(jsDocOptionality.js, 2, 1))
36+
>pInst : Symbol(pInst, Decl(jsDocOptionality.js, 11, 3))
37+
>optionalParam : Symbol(MyClass.optionalParam, Decl(jsDocOptionality.js, 2, 1))
38+
Lines changed: 53 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,53 @@
1+
=== tests/cases/compiler/jsDocOptionality.js ===
2+
function MyClass() {
3+
>MyClass : () => void
4+
5+
this.prop = null;
6+
>this.prop = null : null
7+
>this.prop : any
8+
>this : any
9+
>prop : any
10+
>null : null
11+
}
12+
/**
13+
* @param {string} required
14+
* @param {string} [notRequired]
15+
* @returns {MyClass}
16+
*/
17+
MyClass.prototype.optionalParam = function(required, notRequired) {
18+
>MyClass.prototype.optionalParam = function(required, notRequired) { return this;} : (required: string, notRequired?: string) => { prop: null; optionalParam: any; }
19+
>MyClass.prototype.optionalParam : any
20+
>MyClass.prototype : any
21+
>MyClass : () => void
22+
>prototype : any
23+
>optionalParam : any
24+
>function(required, notRequired) { return this;} : (required: string, notRequired?: string) => { prop: null; optionalParam: any; }
25+
>required : string
26+
>notRequired : string
27+
28+
return this;
29+
>this : { prop: null; optionalParam: (required: string, notRequired?: string) => { prop: null; optionalParam: any; }; }
30+
31+
};
32+
let pInst = new MyClass();
33+
>pInst : { prop: null; optionalParam: (required: string, notRequired?: string) => { prop: null; optionalParam: any; }; }
34+
>new MyClass() : { prop: null; optionalParam: (required: string, notRequired?: string) => { prop: null; optionalParam: any; }; }
35+
>MyClass : () => void
36+
37+
let c1 = pInst.optionalParam('hello')
38+
>c1 : { prop: null; optionalParam: (required: string, notRequired?: string) => { prop: null; optionalParam: any; }; }
39+
>pInst.optionalParam('hello') : { prop: null; optionalParam: (required: string, notRequired?: string) => { prop: null; optionalParam: any; }; }
40+
>pInst.optionalParam : (required: string, notRequired?: string) => { prop: null; optionalParam: any; }
41+
>pInst : { prop: null; optionalParam: (required: string, notRequired?: string) => { prop: null; optionalParam: any; }; }
42+
>optionalParam : (required: string, notRequired?: string) => { prop: null; optionalParam: any; }
43+
>'hello' : string
44+
45+
let c2 = pInst.optionalParam('hello', null)
46+
>c2 : { prop: null; optionalParam: (required: string, notRequired?: string) => { prop: null; optionalParam: any; }; }
47+
>pInst.optionalParam('hello', null) : { prop: null; optionalParam: (required: string, notRequired?: string) => { prop: null; optionalParam: any; }; }
48+
>pInst.optionalParam : (required: string, notRequired?: string) => { prop: null; optionalParam: any; }
49+
>pInst : { prop: null; optionalParam: (required: string, notRequired?: string) => { prop: null; optionalParam: any; }; }
50+
>optionalParam : (required: string, notRequired?: string) => { prop: null; optionalParam: any; }
51+
>'hello' : string
52+
>null : null
53+
Lines changed: 17 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,17 @@
1+
// @allowJs: true
2+
// @out: out_1.js
3+
// @filename: jsDocOptionality.js
4+
function MyClass() {
5+
this.prop = null;
6+
}
7+
/**
8+
* @param {string} required
9+
* @param {string} [notRequired]
10+
* @returns {MyClass}
11+
*/
12+
MyClass.prototype.optionalParam = function(required, notRequired) {
13+
return this;
14+
};
15+
let pInst = new MyClass();
16+
let c1 = pInst.optionalParam('hello')
17+
let c2 = pInst.optionalParam('hello', null)

0 commit comments

Comments
 (0)