Skip to content

Commit ee9ec8e

Browse files
fix: don't require Finnish notation or Subject suffixes for forkJoin or combineLatest properties (#212)
Resolves #40 ### Before ```ts combineLatest({ number$: of(0), letterSubject$: new BehaviorSubject('a') }); ``` ### After ```ts combineLatest({ number: of(0), letter: new BehaviorSubject('a') }); ``` --------- Co-authored-by: Jason Weinzierl <weinzierljason@gmail.com>
1 parent 5662966 commit ee9ec8e

File tree

9 files changed

+58
-5
lines changed

9 files changed

+58
-5
lines changed

docs/rules/finnish.md

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -18,6 +18,9 @@ Examples of **correct** code for this rule:
1818

1919
```ts
2020
const answer$ = of(42, 54);
21+
22+
// The static observable creators that accept a sources object are exempt from this rule.
23+
combineLatest({ answer: of(42, 54) });
2124
```
2225

2326
## Options

docs/rules/suffix-subjects.md

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -23,6 +23,9 @@ Examples of **correct** code for this rule:
2323
```ts
2424
const answersSubject = new Subject<number>();
2525
const answersSubject$ = new Subject<number>();
26+
27+
// The static observable creators that accept a sources object are exempt from this rule.
28+
combineLatest({ answers: new Subject<number>() });
2629
```
2730

2831
## Options

src/constants.ts

Lines changed: 9 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,14 @@
11
export const defaultObservable = String.raw`[Aa]ction(s|s\$|\$)$`;
22

3+
/**
4+
* The names of static observable creators
5+
* that accept a sources object as input.
6+
*/
7+
export const SOURCES_OBJECT_ACCEPTING_STATIC_OBSERVABLE_CREATORS = [
8+
'combineLatest',
9+
'forkJoin',
10+
];
11+
312
/**
413
* The names of operators that are safe to be used after
514
* operators like `takeUntil` that complete the observable.

src/rules/finnish.ts

Lines changed: 4 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -2,8 +2,9 @@ import { AST_NODE_TYPES, TSESTree as es, ESLintUtils } from '@typescript-eslint/
22
import {
33
findParent,
44
getLoc,
5-
getTypeServices } from '../etc';
6-
import { ruleCreator } from '../utils';
5+
getTypeServices,
6+
} from '../etc';
7+
import { isSourcesObjectAcceptingStaticObservableCreator, ruleCreator } from '../utils';
78

89
const defaultOptions: readonly {
910
functions?: boolean;
@@ -228,7 +229,7 @@ export const finnishRule = ruleCreator({
228229
) => {
229230
if (validate.properties) {
230231
const parent = node.parent as es.Property;
231-
if (node === parent.key) {
232+
if (node === parent.key && !isSourcesObjectAcceptingStaticObservableCreator(parent.parent.parent)) {
232233
checkNode(node);
233234
}
234235
}

src/rules/suffix-subjects.ts

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -4,7 +4,7 @@ import {
44
getLoc,
55
getTypeServices,
66
} from '../etc';
7-
import { escapeRegExp, ruleCreator } from '../utils';
7+
import { escapeRegExp, isSourcesObjectAcceptingStaticObservableCreator, ruleCreator } from '../utils';
88

99
const defaultOptions: readonly {
1010
parameters?: boolean;
@@ -161,7 +161,7 @@ export const suffixSubjectsRule = ruleCreator({
161161
) => {
162162
if (validate.properties) {
163163
const parent = node.parent as es.Property;
164-
if (node === parent.key) {
164+
if (node === parent.key && !isSourcesObjectAcceptingStaticObservableCreator(parent.parent.parent)) {
165165
checkNode(node);
166166
}
167167
}

src/utils/index.ts

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,5 @@
11
export * from './create-regexp-for-words';
22
export * from './escape-regexp';
33
export * from './find-is-last-operator-order-valid';
4+
export * from './is-sources-object-accepting-static-observable-creator';
45
export * from './rule-creator';
Lines changed: 18 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,18 @@
1+
import { TSESTree as es } from '@typescript-eslint/utils';
2+
import { SOURCES_OBJECT_ACCEPTING_STATIC_OBSERVABLE_CREATORS } from '../constants';
3+
import { isCallExpression, isIdentifier } from '../etc/is';
4+
5+
/**
6+
* Returns true if the given expression is a call to a
7+
* sourcesObject-accepting static observable creator.
8+
*
9+
* @example
10+
* ```ts
11+
* combineLatest({ a$: of(), b$: of() });
12+
* ```
13+
*/
14+
export function isSourcesObjectAcceptingStaticObservableCreator(expression: es.Node): boolean {
15+
return isCallExpression(expression)
16+
&& isIdentifier(expression.callee)
17+
&& SOURCES_OBJECT_ACCEPTING_STATIC_OBSERVABLE_CREATORS.includes(expression.callee.name);
18+
}

tests/rules/finnish.test.ts

Lines changed: 9 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -200,6 +200,15 @@ ruleTester({ types: true }).run('finnish', finnishRule, {
200200
`,
201201
options: [{ properties: false }],
202202
},
203+
{
204+
code: stripIndent`
205+
// Static observable creators that accept a sources object
206+
import { of, combineLatest, forkJoin } from "rxjs";
207+
208+
combineLatest({ one: of(0), two: of('a') });
209+
forkJoin({ one: of(0), two: of('a') });
210+
`,
211+
},
203212
],
204213
invalid: [
205214
fromFixture(

tests/rules/suffix-subjects.test.ts

Lines changed: 9 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -282,6 +282,15 @@ ruleTester({ types: true }).run('suffix-subjects', suffixSubjectsRule, {
282282
const mySubject = new MySubject<number>();
283283
`,
284284
},
285+
{
286+
code: stripIndent`
287+
// Static observable creators that accept a sources object
288+
import { Subject, BehaviorSubject, combineLatest, forkJoin } from "rxjs";
289+
290+
combineLatest({ one: new Subject<number>(), two: new BehaviorSubject('a') });
291+
forkJoin({ one: new Subject<number>(), two: new BehaviorSubject('a') });
292+
`,
293+
},
285294
],
286295
invalid: [
287296
fromFixture(

0 commit comments

Comments
 (0)