Skip to content

Commit dfc0b58

Browse files
authored
Preserve arity for preserving js optional parameters (#37173)
1 parent 7a82b74 commit dfc0b58

File tree

6 files changed

+77
-3
lines changed

6 files changed

+77
-3
lines changed

src/compiler/checker.ts

+8-3
Original file line numberDiff line numberDiff line change
@@ -10510,7 +10510,7 @@ namespace ts {
1051010510
const signature = getSignatureFromDeclaration(node.parent);
1051110511
const parameterIndex = node.parent.parameters.indexOf(node);
1051210512
Debug.assert(parameterIndex >= 0);
10513-
return parameterIndex >= getMinArgumentCount(signature);
10513+
return parameterIndex >= getMinArgumentCount(signature, /*strongArityForUntypedJS*/ true);
1051410514
}
1051510515
const iife = getImmediatelyInvokedFunctionExpression(node.parent);
1051610516
if (iife) {
@@ -10601,6 +10601,9 @@ namespace ts {
1060110601
isValueSignatureDeclaration(declaration) &&
1060210602
!hasJSDocParameterTags(declaration) &&
1060310603
!getJSDocType(declaration);
10604+
if (isUntypedSignatureInJSFile) {
10605+
flags |= SignatureFlags.IsUntypedSignatureInJSFile;
10606+
}
1060410607

1060510608
// If this is a JSDoc construct signature, then skip the first parameter in the
1060610609
// parameter list. The first parameter represents the return type of the construct
@@ -10631,7 +10634,6 @@ namespace ts {
1063110634
const isOptionalParameter = isOptionalJSDocParameterTag(param) ||
1063210635
param.initializer || param.questionToken || param.dotDotDotToken ||
1063310636
iife && parameters.length > iife.arguments.length && !type ||
10634-
isUntypedSignatureInJSFile ||
1063510637
isJSDocOptionalParameter(param);
1063610638
if (!isOptionalParameter) {
1063710639
minArgumentCount = parameters.length;
@@ -26375,7 +26377,7 @@ namespace ts {
2637526377
return length;
2637626378
}
2637726379

26378-
function getMinArgumentCount(signature: Signature) {
26380+
function getMinArgumentCount(signature: Signature, strongArityForUntypedJS?: boolean) {
2637926381
if (signatureHasRestParameter(signature)) {
2638026382
const restType = getTypeOfSymbol(signature.parameters[signature.parameters.length - 1]);
2638126383
if (isTupleType(restType)) {
@@ -26385,6 +26387,9 @@ namespace ts {
2638526387
}
2638626388
}
2638726389
}
26390+
if (!strongArityForUntypedJS && signature.flags & SignatureFlags.IsUntypedSignatureInJSFile) {
26391+
return 0;
26392+
}
2638826393
return signature.minArgumentCount;
2638926394
}
2639026395

src/compiler/types.ts

+1
Original file line numberDiff line numberDiff line change
@@ -4817,6 +4817,7 @@ namespace ts {
48174817
HasLiteralTypes = 1 << 1, // Indicates signature is specialized
48184818
IsInnerCallChain = 1 << 2, // Indicates signature comes from a CallChain nested in an outer OptionalChain
48194819
IsOuterCallChain = 1 << 3, // Indicates signature comes from a CallChain that is the outermost chain of an optional expression
4820+
IsUntypedSignatureInJSFile = 1 << 4, // Indicates signature is from a js file and has no types
48204821

48214822
// We do not propagate `IsInnerCallChain` to instantiated signatures, as that would result in us
48224823
// attempting to add `| undefined` on each recursive call to `getReturnTypeOfSignature` when
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,27 @@
1+
//// [bar.js]
2+
export class Z {
3+
f(x = 1, y) {
4+
return [x, y];
5+
}
6+
}
7+
8+
//// [bar.js]
9+
"use strict";
10+
Object.defineProperty(exports, "__esModule", { value: true });
11+
exports.Z = void 0;
12+
var Z = /** @class */ (function () {
13+
function Z() {
14+
}
15+
Z.prototype.f = function (x, y) {
16+
if (x === void 0) { x = 1; }
17+
return [x, y];
18+
};
19+
return Z;
20+
}());
21+
exports.Z = Z;
22+
23+
24+
//// [bar.d.ts]
25+
export class Z {
26+
f(x: number, y: any): any[];
27+
}
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,14 @@
1+
=== tests/cases/conformance/jsdoc/declarations/bar.js ===
2+
export class Z {
3+
>Z : Symbol(Z, Decl(bar.js, 0, 0))
4+
5+
f(x = 1, y) {
6+
>f : Symbol(Z.f, Decl(bar.js, 0, 16))
7+
>x : Symbol(x, Decl(bar.js, 1, 6))
8+
>y : Symbol(y, Decl(bar.js, 1, 12))
9+
10+
return [x, y];
11+
>x : Symbol(x, Decl(bar.js, 1, 6))
12+
>y : Symbol(y, Decl(bar.js, 1, 12))
13+
}
14+
}
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,16 @@
1+
=== tests/cases/conformance/jsdoc/declarations/bar.js ===
2+
export class Z {
3+
>Z : Z
4+
5+
f(x = 1, y) {
6+
>f : (x: number, y: any) => any[]
7+
>x : number
8+
>1 : 1
9+
>y : any
10+
11+
return [x, y];
12+
>[x, y] : any[]
13+
>x : number
14+
>y : any
15+
}
16+
}
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,11 @@
1+
// @allowJs: true
2+
// @checkJs: true
3+
// @target: es5
4+
// @outDir: ./out
5+
// @declaration: true
6+
// @filename: bar.js
7+
export class Z {
8+
f(x = 1, y) {
9+
return [x, y];
10+
}
11+
}

0 commit comments

Comments
 (0)