Skip to content

Commit a75f26e

Browse files
authored
fix(42238): emit this parameter in function declaration (#46511)
1 parent f11f14b commit a75f26e

File tree

6 files changed

+72
-9
lines changed

6 files changed

+72
-9
lines changed

src/compiler/checker.ts

Lines changed: 21 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -5657,8 +5657,8 @@ namespace ts {
56575657
const expandedParams = getExpandedParameters(signature, /*skipUnionExpanding*/ true)[0];
56585658
// If the expanded parameter list had a variadic in a non-trailing position, don't expand it
56595659
const parameters = (some(expandedParams, p => p !== expandedParams[expandedParams.length - 1] && !!(getCheckFlags(p) & CheckFlags.RestParameter)) ? signature.parameters : expandedParams).map(parameter => symbolToParameterDeclaration(parameter, context, kind === SyntaxKind.Constructor, options?.privateSymbolVisitor, options?.bundledImports));
5660-
if (signature.thisParameter) {
5661-
const thisParameter = symbolToParameterDeclaration(signature.thisParameter, context);
5660+
const thisParameter = tryGetThisParameterDeclaration(signature, context);
5661+
if (thisParameter) {
56625662
parameters.unshift(thisParameter);
56635663
}
56645664

@@ -5713,6 +5713,25 @@ namespace ts {
57135713
return node;
57145714
}
57155715

5716+
function tryGetThisParameterDeclaration(signature: Signature, context: NodeBuilderContext) {
5717+
if (signature.thisParameter) {
5718+
return symbolToParameterDeclaration(signature.thisParameter, context);
5719+
}
5720+
if (signature.declaration) {
5721+
const thisTag = getJSDocThisTag(signature.declaration);
5722+
if (thisTag && thisTag.typeExpression) {
5723+
return factory.createParameterDeclaration(
5724+
/* decorators */ undefined,
5725+
/* modifiers */ undefined,
5726+
/* dotDotDotToken */ undefined,
5727+
"this",
5728+
/* questionToken */ undefined,
5729+
typeToTypeNodeHelper(getTypeFromTypeNode(thisTag.typeExpression), context)
5730+
);
5731+
}
5732+
}
5733+
}
5734+
57165735
function typeParameterToDeclarationWithConstraint(type: TypeParameter, context: NodeBuilderContext, constraintNode: TypeNode | undefined): TypeParameterDeclaration {
57175736
const savedContextFlags = context.flags;
57185737
context.flags &= ~NodeBuilderFlags.WriteTypeParametersInQualifiedName; // Avoids potential infinite loop when building for a claimspace with a generic

tests/baselines/reference/thisTag1.types

Lines changed: 7 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -4,7 +4,7 @@
44
* @return {number}
55
*/
66
function f(s) {
7-
>f : (s: string) => number
7+
>f : (this: { n: number; }, s: string) => number
88
>s : string
99

1010
return this.n + s.length
@@ -18,20 +18,20 @@ function f(s) {
1818
}
1919

2020
const o = {
21-
>o : { f: (s: string) => number; n: number; }
22-
>{ f, n: 1} : { f: (s: string) => number; n: number; }
21+
>o : { f: (this: { n: number; }, s: string) => number; n: number; }
22+
>{ f, n: 1} : { f: (this: { n: number; }, s: string) => number; n: number; }
2323

2424
f,
25-
>f : (s: string) => number
25+
>f : (this: { n: number; }, s: string) => number
2626

2727
n: 1
2828
>n : number
2929
>1 : 1
3030
}
3131
o.f('hi')
3232
>o.f('hi') : number
33-
>o.f : (s: string) => number
34-
>o : { f: (s: string) => number; n: number; }
35-
>f : (s: string) => number
33+
>o.f : (this: { n: number; }, s: string) => number
34+
>o : { f: (this: { n: number; }, s: string) => number; n: number; }
35+
>f : (this: { n: number; }, s: string) => number
3636
>'hi' : "hi"
3737

tests/baselines/reference/thisTag2.js

Lines changed: 15 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,15 @@
1+
//// [a.js]
2+
/** @this {string} */
3+
export function f1() {}
4+
5+
/** @this */
6+
export function f2() {}
7+
8+
9+
10+
11+
//// [a.d.ts]
12+
/** @this {string} */
13+
export function f1(this: string): void;
14+
/** @this */
15+
export function f2(this: any): void;
Lines changed: 9 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,9 @@
1+
=== tests/cases/conformance/jsdoc/a.js ===
2+
/** @this {string} */
3+
export function f1() {}
4+
>f1 : Symbol(f1, Decl(a.js, 0, 0))
5+
6+
/** @this */
7+
export function f2() {}
8+
>f2 : Symbol(f2, Decl(a.js, 1, 23))
9+
Lines changed: 9 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,9 @@
1+
=== tests/cases/conformance/jsdoc/a.js ===
2+
/** @this {string} */
3+
export function f1() {}
4+
>f1 : (this: string) => void
5+
6+
/** @this */
7+
export function f2() {}
8+
>f2 : (this: any) => void
9+
Lines changed: 11 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,11 @@
1+
// @target: esnext
2+
// @allowJs: true
3+
// @declaration: true
4+
// @emitDeclarationOnly: true
5+
// @filename: a.js
6+
7+
/** @this {string} */
8+
export function f1() {}
9+
10+
/** @this */
11+
export function f2() {}

0 commit comments

Comments
 (0)