Skip to content

Commit 5449489

Browse files
a-tarasyuksandersn
andauthored
fix(55796): JSDoc does not support @this when using an arrow function as method in class (#55877)
Co-authored-by: Nathan Shively-Sanders <[email protected]>
1 parent 781cc19 commit 5449489

File tree

5 files changed

+96
-0
lines changed

5 files changed

+96
-0
lines changed

src/compiler/checker.ts

Lines changed: 11 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -780,6 +780,7 @@ import {
780780
JSDocSatisfiesTag,
781781
JSDocSignature,
782782
JSDocTemplateTag,
783+
JSDocThisTag,
783784
JSDocTypeAssertion,
784785
JSDocTypedefTag,
785786
JSDocTypeExpression,
@@ -41240,6 +41241,7 @@ export function createTypeChecker(host: TypeCheckerHost): TypeChecker {
4124041241
function checkJSDocParameterTag(node: JSDocParameterTag) {
4124141242
checkSourceElement(node.typeExpression);
4124241243
}
41244+
4124341245
function checkJSDocPropertyTag(node: JSDocPropertyTag) {
4124441246
checkSourceElement(node.typeExpression);
4124541247
}
@@ -41255,6 +41257,13 @@ export function createTypeChecker(host: TypeCheckerHost): TypeChecker {
4125541257
}
4125641258
}
4125741259

41260+
function checkJSDocThisTag(node: JSDocThisTag) {
41261+
const host = getEffectiveJSDocHost(node);
41262+
if (host && isArrowFunction(host)) {
41263+
error(node.tagName, Diagnostics.An_arrow_function_cannot_have_a_this_parameter);
41264+
}
41265+
}
41266+
4125841267
function checkJSDocImplementsTag(node: JSDocImplementsTag): void {
4125941268
const classLike = getEffectiveJSDocHost(node);
4126041269
if (!classLike || !isClassDeclaration(classLike) && !isClassExpression(classLike)) {
@@ -45973,6 +45982,8 @@ export function createTypeChecker(host: TypeCheckerHost): TypeChecker {
4597345982
return checkJSDocAccessibilityModifiers(node as JSDocPublicTag | JSDocProtectedTag | JSDocPrivateTag);
4597445983
case SyntaxKind.JSDocSatisfiesTag:
4597545984
return checkJSDocSatisfiesTag(node as JSDocSatisfiesTag);
45985+
case SyntaxKind.JSDocThisTag:
45986+
return checkJSDocThisTag(node as JSDocThisTag);
4597645987
case SyntaxKind.IndexedAccessType:
4597745988
return checkIndexedAccessType(node as IndexedAccessTypeNode);
4597845989
case SyntaxKind.MappedType:
Lines changed: 21 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,21 @@
1+
/a.js(7,9): error TS2730: An arrow function cannot have a 'this' parameter.
2+
/a.js(10,21): error TS2339: Property 'fn' does not exist on type 'C'.
3+
4+
5+
==== /a.js (2 errors) ====
6+
/**
7+
* @typedef {{fn(a: string): void}} T
8+
*/
9+
10+
class C {
11+
/**
12+
* @this {T}
13+
~~~~
14+
!!! error TS2730: An arrow function cannot have a 'this' parameter.
15+
* @param {string} a
16+
*/
17+
p = (a) => this.fn("" + a);
18+
~~
19+
!!! error TS2339: Property 'fn' does not exist on type 'C'.
20+
}
21+
Lines changed: 21 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,21 @@
1+
//// [tests/cases/conformance/jsdoc/thisTag3.ts] ////
2+
3+
=== /a.js ===
4+
/**
5+
* @typedef {{fn(a: string): void}} T
6+
*/
7+
8+
class C {
9+
>C : Symbol(C, Decl(a.js, 0, 0))
10+
11+
/**
12+
* @this {T}
13+
* @param {string} a
14+
*/
15+
p = (a) => this.fn("" + a);
16+
>p : Symbol(C.p, Decl(a.js, 4, 9))
17+
>a : Symbol(a, Decl(a.js, 9, 9))
18+
>this : Symbol(C, Decl(a.js, 0, 0))
19+
>a : Symbol(a, Decl(a.js, 9, 9))
20+
}
21+
Lines changed: 27 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,27 @@
1+
//// [tests/cases/conformance/jsdoc/thisTag3.ts] ////
2+
3+
=== /a.js ===
4+
/**
5+
* @typedef {{fn(a: string): void}} T
6+
*/
7+
8+
class C {
9+
>C : C
10+
11+
/**
12+
* @this {T}
13+
* @param {string} a
14+
*/
15+
p = (a) => this.fn("" + a);
16+
>p : (this: T, a: string) => any
17+
>(a) => this.fn("" + a) : (this: T, a: string) => any
18+
>a : string
19+
>this.fn("" + a) : any
20+
>this.fn : any
21+
>this : this
22+
>fn : any
23+
>"" + a : string
24+
>"" : ""
25+
>a : string
26+
}
27+
Lines changed: 16 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,16 @@
1+
// @allowJs: true
2+
// @checkJs: true
3+
// @noEmit: true
4+
// @filename: /a.js
5+
6+
/**
7+
* @typedef {{fn(a: string): void}} T
8+
*/
9+
10+
class C {
11+
/**
12+
* @this {T}
13+
* @param {string} a
14+
*/
15+
p = (a) => this.fn("" + a);
16+
}

0 commit comments

Comments
 (0)