Skip to content

Commit ddf5660

Browse files
tadhgmisterTadhg McDonald-Jensen
and
Tadhg McDonald-Jensen
authored
feat(eslint-plugin): [no-invalid-void-type] add option to allow this: void (typescript-eslint#2481)
* fix: implemented allowThisAsVoid option * Update packages/eslint-plugin/src/rules/no-invalid-void-type.ts * Update packages/eslint-plugin/src/rules/no-invalid-void-type.ts * Update packages/eslint-plugin/docs/rules/no-invalid-void-type.md incorperate review. Co-authored-by: Tadhg McDonald-Jensen <tadhg.mcdonaldjensen@carleton.ca>
1 parent 8025777 commit ddf5660

File tree

3 files changed

+109
-8
lines changed

3 files changed

+109
-8
lines changed

packages/eslint-plugin/docs/rules/no-invalid-void-type.md

Lines changed: 19 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -54,10 +54,12 @@ type stillVoid = void | never;
5454
```ts
5555
interface Options {
5656
allowInGenericTypeArguments?: boolean | string[];
57+
allowAsThisParameter?: boolean;
5758
}
5859

5960
const defaultOptions: Options = {
6061
allowInGenericTypeArguments: true,
62+
allowAsThisParameter: false,
6163
};
6264
```
6365

@@ -97,6 +99,23 @@ type AllowedVoid = Ex.Mx.Tx<void>;
9799
type AllowedVoidUnion = void | Ex.Mx.Tx<void>;
98100
```
99101

102+
#### `allowAsThisParameter`
103+
104+
This option allows specifying a `this` parameter of a function to be `void` when set to `true`.
105+
This pattern can be useful to explicitly label function types that do not use a `this` argument. [See the TypeScript docs for more information](https://www.typescriptlang.org/docs/handbook/functions.html#this-parameters-in-callbacks).
106+
107+
This option is `false` by default.
108+
109+
The following patterns are considered warnings with `{ allowAsThisParameter: false }` but valid with `{ allowAsThisParameter: true }`:
110+
111+
```ts
112+
function doThing(this: void) {}
113+
class Example {
114+
static helper(this: void) {}
115+
callback(this: void) {}
116+
}
117+
```
118+
100119
## When Not To Use It
101120

102121
If you don't care about if `void` is used with other types,

packages/eslint-plugin/src/rules/no-invalid-void-type.ts

Lines changed: 37 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -5,13 +5,16 @@ import {
55
import * as util from '../util';
66

77
interface Options {
8-
allowInGenericTypeArguments: boolean | string[];
8+
allowInGenericTypeArguments?: boolean | string[];
9+
allowAsThisParameter?: boolean;
910
}
1011

1112
type MessageIds =
1213
| 'invalidVoidForGeneric'
1314
| 'invalidVoidNotReturnOrGeneric'
14-
| 'invalidVoidNotReturn';
15+
| 'invalidVoidNotReturn'
16+
| 'invalidVoidNotReturnOrThisParam'
17+
| 'invalidVoidNotReturnOrThisParamOrGeneric';
1518

1619
export default util.createRule<[Options], MessageIds>({
1720
name: 'no-invalid-void-type',
@@ -29,6 +32,10 @@ export default util.createRule<[Options], MessageIds>({
2932
invalidVoidNotReturnOrGeneric:
3033
'void is only valid as a return type or generic type variable',
3134
invalidVoidNotReturn: 'void is only valid as a return type',
35+
invalidVoidNotReturnOrThisParam:
36+
'void is only valid as return type or type of `this` parameter',
37+
invalidVoidNotReturnOrThisParamOrGeneric:
38+
'void is only valid as a return type or generic type variable or the type of a `this` parameter',
3239
},
3340
schema: [
3441
{
@@ -44,13 +51,18 @@ export default util.createRule<[Options], MessageIds>({
4451
},
4552
],
4653
},
54+
allowAsThisParameter: {
55+
type: 'boolean',
56+
},
4757
},
4858
additionalProperties: false,
4959
},
5060
],
5161
},
52-
defaultOptions: [{ allowInGenericTypeArguments: true }],
53-
create(context, [{ allowInGenericTypeArguments }]) {
62+
defaultOptions: [
63+
{ allowInGenericTypeArguments: true, allowAsThisParameter: false },
64+
],
65+
create(context, [{ allowInGenericTypeArguments, allowAsThisParameter }]) {
5466
const validParents: AST_NODE_TYPES[] = [
5567
AST_NODE_TYPES.TSTypeAnnotation, //
5668
];
@@ -110,7 +122,9 @@ export default util.createRule<[Options], MessageIds>({
110122

111123
if (!allowInGenericTypeArguments) {
112124
context.report({
113-
messageId: 'invalidVoidNotReturn',
125+
messageId: allowAsThisParameter
126+
? 'invalidVoidNotReturnOrThisParam'
127+
: 'invalidVoidNotReturn',
114128
node,
115129
});
116130
}
@@ -159,6 +173,16 @@ export default util.createRule<[Options], MessageIds>({
159173
return;
160174
}
161175

176+
// this parameter is ok to be void.
177+
if (
178+
allowAsThisParameter &&
179+
node.parent.type === AST_NODE_TYPES.TSTypeAnnotation &&
180+
node.parent.parent.type === AST_NODE_TYPES.Identifier &&
181+
node.parent.parent.name === 'this'
182+
) {
183+
return;
184+
}
185+
162186
// default cases
163187
if (
164188
validParents.includes(node.parent.type) &&
@@ -168,9 +192,14 @@ export default util.createRule<[Options], MessageIds>({
168192
}
169193

170194
context.report({
171-
messageId: allowInGenericTypeArguments
172-
? 'invalidVoidNotReturnOrGeneric'
173-
: 'invalidVoidNotReturn',
195+
messageId:
196+
allowInGenericTypeArguments && allowAsThisParameter
197+
? 'invalidVoidNotReturnOrThisParamOrGeneric'
198+
: allowInGenericTypeArguments
199+
? 'invalidVoidNotReturnOrGeneric'
200+
: allowAsThisParameter
201+
? 'invalidVoidNotReturnOrThisParam'
202+
: 'invalidVoidNotReturn',
174203
node,
175204
});
176205
},

packages/eslint-plugin/tests/rules/no-invalid-void-type.test.ts

Lines changed: 53 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -538,3 +538,56 @@ async function foo(bar: () => void | Promise<void>) {
538538
},
539539
],
540540
});
541+
542+
ruleTester.run('allowAsThisParameter: true', rule, {
543+
valid: [
544+
{
545+
code: 'function f(this: void) {}',
546+
options: [{ allowAsThisParameter: true }],
547+
},
548+
{
549+
code: `
550+
class Test {
551+
public static helper(this: void) {}
552+
method(this: void) {}
553+
}
554+
`,
555+
options: [{ allowAsThisParameter: true }],
556+
},
557+
],
558+
invalid: [
559+
{
560+
code: 'type alias = void;',
561+
options: [
562+
{ allowAsThisParameter: true, allowInGenericTypeArguments: true },
563+
],
564+
errors: [
565+
{
566+
messageId: 'invalidVoidNotReturnOrThisParamOrGeneric',
567+
},
568+
],
569+
},
570+
{
571+
code: 'type alias = void;',
572+
options: [
573+
{ allowAsThisParameter: true, allowInGenericTypeArguments: false },
574+
],
575+
errors: [
576+
{
577+
messageId: 'invalidVoidNotReturnOrThisParam',
578+
},
579+
],
580+
},
581+
{
582+
code: 'type alias = Array<void>;',
583+
options: [
584+
{ allowAsThisParameter: true, allowInGenericTypeArguments: false },
585+
],
586+
errors: [
587+
{
588+
messageId: 'invalidVoidNotReturnOrThisParam',
589+
},
590+
],
591+
},
592+
],
593+
});

0 commit comments

Comments
 (0)
pFad - Phonifier reborn

Pfad - The Proxy pFad of © 2024 Garber Painting. All rights reserved.

Note: This service is not intended for secure transactions such as banking, social media, email, or purchasing. Use at your own risk. We assume no liability whatsoever for broken pages.


Alternative Proxies:

Alternative Proxy

pFad Proxy

pFad v3 Proxy

pFad v4 Proxy