Skip to content

Commit 5662966

Browse files
fix(no-explicit-generics): allow explicit union types (#210)
Now something like the following will be allowed: ```ts const subject = new BehaviorSubject<ISomeType | null>(null); ``` Resolves #77 --------- Signed-off-by: Chris Barr <[email protected]> Co-authored-by: Jason Weinzierl <[email protected]>
1 parent 7588757 commit 5662966

File tree

4 files changed

+32
-9
lines changed

4 files changed

+32
-9
lines changed

docs/rules/no-explicit-generics.md

Lines changed: 5 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -10,7 +10,7 @@ Examples of **incorrect** code for this rule:
1010

1111
```ts
1212
import { BehaviorSubject } from "rxjs";
13-
const subject = new BehaviorSubject<number>(42);
13+
const subject = new BehaviorSubject<number>(42); //Adding a type here is not useful
1414
```
1515

1616
Examples of **correct** code for this rule:
@@ -20,11 +20,10 @@ import { BehaviorSubject } from "rxjs";
2020
const subject = new BehaviorSubject(42);
2121
```
2222

23-
## When Not To Use It
24-
25-
This rule has known problems in the latest release:
26-
27-
- ([#77](https://github.com/JasonWeinzierl/eslint-plugin-rxjs-x/issues/77)) Type unions cause false positives e.g. `new BehaviorSubject<number | null>(null)` will be incorrectly caught by this rule.
23+
```ts
24+
import { BehaviorSubject } from "rxjs";
25+
const subject = new BehaviorSubject<ISomeType | null>(null); //Allow union types to be defined, useful when things can be nullable
26+
```
2827

2928
## Resources
3029

src/etc/is.ts

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -144,6 +144,10 @@ export function isUnaryExpression(node: TSESTree.Node): node is TSESTree.UnaryEx
144144
return node.type === AST_NODE_TYPES.UnaryExpression;
145145
}
146146

147+
export function isUnionType(node: TSESTree.Node): node is TSESTree.TSUnionType {
148+
return node.type === AST_NODE_TYPES.TSUnionType;
149+
}
150+
147151
export function isVariableDeclarator(
148152
node: TSESTree.Node,
149153
): node is TSESTree.VariableDeclarator {

src/rules/no-explicit-generics.ts

Lines changed: 7 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,5 @@
11
import { TSESTree as es } from '@typescript-eslint/utils';
2-
import { isArrayExpression, isObjectExpression } from '../etc';
2+
import { isArrayExpression, isObjectExpression, isUnionType } from '../etc';
33
import { ruleCreator } from '../utils';
44

55
export const noExplicitGenericsRule = ruleCreator({
@@ -28,7 +28,9 @@ export const noExplicitGenericsRule = ruleCreator({
2828
const {
2929
arguments: [value],
3030
} = parent;
31-
if (isArrayExpression(value) || isObjectExpression(value)) {
31+
32+
const typeArgs = parent.typeArguments?.params[0];
33+
if (isArrayExpression(value) || isObjectExpression(value) || (typeArgs && isUnionType(typeArgs))) {
3234
return;
3335
}
3436
report(node);
@@ -39,7 +41,9 @@ export const noExplicitGenericsRule = ruleCreator({
3941
const {
4042
arguments: [, value],
4143
} = parent;
42-
if (isArrayExpression(value) || isObjectExpression(value)) {
44+
45+
const typeArgs = parent.typeArguments?.params[0];
46+
if (isArrayExpression(value) || isObjectExpression(value) || (typeArgs && isUnionType(typeArgs))) {
4347
return;
4448
}
4549
report(node);

tests/rules/no-explicit-generics.test.ts

Lines changed: 16 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -38,6 +38,22 @@ ruleTester({ types: false }).run('no-explicit-generics', noExplicitGenericsRule,
3838
const h = new Notification<{ answer?: number }>("N", {});
3939
`,
4040
},
41+
{
42+
code: stripIndent`
43+
// with union types
44+
import { BehaviorSubject, Notification } from "rxjs";
45+
const a = new BehaviorSubject<number | null>(null);
46+
const b = new BehaviorSubject<number | null>(42);
47+
const c = new BehaviorSubject<{ answer: number } | null>({ answer: 42 });
48+
const d = new BehaviorSubject<{ answer: number } | null>(null);
49+
const e = new BehaviorSubject<{ answer?: number }>({});
50+
const f = new Notification<number | null>("N", 42);
51+
const g = new Notification<number | null>("N", null);
52+
const h = new Notification<{ answer: number } | null>("N", { answer: 42 });
53+
const i = new Notification<{ answer?: number } | null>("N", {});
54+
const j = new Notification<{ answer?: number } | null>("N", null);
55+
`,
56+
},
4157
],
4258
invalid: [
4359
fromFixture(

0 commit comments

Comments
 (0)