Thanks to visit codestin.com
Credit goes to github.com

Skip to content

Commit 878dd4a

Browse files
authored
feat(eslint-plugin): [unbound-method] add support for methods with a this: void parameter (typescript-eslint#2796)
1 parent 29428a4 commit 878dd4a

File tree

3 files changed

+47
-10
lines changed

3 files changed

+47
-10
lines changed

packages/eslint-plugin/docs/rules/unbound-method.md

Lines changed: 16 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -23,6 +23,14 @@ myLog();
2323

2424
// This log might later be called with an incorrect scope
2525
const { log } = instance;
26+
27+
// arith.double may refer to `this` internally
28+
const arith = {
29+
double(x: number): number {
30+
return x * 2;
31+
},
32+
};
33+
const { double } = arith;
2634
```
2735

2836
Examples of **correct** code for this rule
@@ -45,6 +53,14 @@ logBound();
4553
// .bind and lambdas will also add a correct scope
4654
const dotBindLog = instance.logBound.bind(instance);
4755
const innerLog = () => instance.logBound();
56+
57+
// arith.double explicitly declares that it does not refer to `this` internally
58+
const arith = {
59+
double(this: void, x: number): number {
60+
return x * 2;
61+
},
62+
};
63+
const { double } = arith;
4864
```
4965

5066
## Options

packages/eslint-plugin/src/rules/unbound-method.ts

Lines changed: 19 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -248,14 +248,27 @@ function isDangerousMethod(symbol: ts.Symbol, ignoreStatic: boolean): boolean {
248248
ts.SyntaxKind.FunctionExpression
249249
);
250250
case ts.SyntaxKind.MethodDeclaration:
251-
case ts.SyntaxKind.MethodSignature:
252-
return !(
253-
ignoreStatic &&
254-
tsutils.hasModifier(
255-
valueDeclaration.modifiers,
256-
ts.SyntaxKind.StaticKeyword,
251+
case ts.SyntaxKind.MethodSignature: {
252+
const decl = valueDeclaration as
253+
| ts.MethodDeclaration
254+
| ts.MethodSignature;
255+
const firstParam = decl.parameters[0];
256+
const thisArgIsVoid =
257+
firstParam?.name.kind === ts.SyntaxKind.Identifier &&
258+
firstParam?.name.escapedText === 'this' &&
259+
firstParam?.type?.kind === ts.SyntaxKind.VoidKeyword;
260+
261+
return (
262+
!thisArgIsVoid &&
263+
!(
264+
ignoreStatic &&
265+
tsutils.hasModifier(
266+
valueDeclaration.modifiers,
267+
ts.SyntaxKind.StaticKeyword,
268+
)
257269
)
258270
);
271+
}
259272
}
260273

261274
return false;

packages/eslint-plugin/tests/rules/unbound-method.test.ts

Lines changed: 12 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -25,6 +25,12 @@ class ContainsMethods {
2525
2626
let instance = new ContainsMethods();
2727
28+
const arith = {
29+
double(this: void, x: number): number {
30+
return x * 2;
31+
}
32+
};
33+
2834
${code}
2935
`;
3036
}
@@ -35,7 +41,7 @@ function addContainsMethodsClassInvalid(
3541
code: addContainsMethodsClass(c),
3642
errors: [
3743
{
38-
line: 12,
44+
line: 18,
3945
messageId: 'unbound',
4046
},
4147
],
@@ -153,6 +159,8 @@ ruleTester.run('unbound-method', rule, {
153159
'if (!!instance.unbound) {}',
154160
'void instance.unbound',
155161
'delete instance.unbound',
162+
163+
'const { double } = arith;',
156164
].map(addContainsMethodsClass),
157165
`
158166
interface RecordA {
@@ -300,15 +308,15 @@ function foo(arg: ContainsMethods | null) {
300308
`),
301309
errors: [
302310
{
303-
line: 14,
311+
line: 20,
304312
messageId: 'unbound',
305313
},
306314
{
307-
line: 15,
315+
line: 21,
308316
messageId: 'unbound',
309317
},
310318
{
311-
line: 16,
319+
line: 22,
312320
messageId: 'unbound',
313321
},
314322
],

0 commit comments

Comments
 (0)