Skip to content

Commit fce2bee

Browse files
fix: support variables and member expression
1 parent 64e758f commit fce2bee

File tree

2 files changed

+64
-6
lines changed

2 files changed

+64
-6
lines changed

src/rules/no-ignored-default-value.ts

Lines changed: 30 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,5 @@
11
import { TSESTree as es } from '@typescript-eslint/utils';
2-
import { getTypeServices, isIdentifier, isImport, isObjectExpression, isProperty } from '../etc';
2+
import { getTypeServices, isIdentifier, isImport, isMemberExpression, isObjectExpression, isProperty } from '../etc';
33
import { ruleCreator } from '../utils';
44

55
export const noIgnoredDefaultValueRule = ruleCreator({
@@ -10,16 +10,16 @@ export const noIgnoredDefaultValueRule = ruleCreator({
1010
requiresTypeChecking: true,
1111
},
1212
messages: {
13-
forbidden: 'Ignoring the default value is forbidden.',
13+
forbidden: 'Not specifying a default value is forbidden.',
1414
},
1515
schema: [],
1616
type: 'problem',
1717
},
1818
name: 'no-ignored-default-value',
1919
create: (context) => {
20-
const { couldBeObservable } = getTypeServices(context);
20+
const { couldBeObservable, getType } = getTypeServices(context);
2121

22-
function checkConfig(configArg: es.ObjectExpression) {
22+
function checkConfigObj(configArg: es.ObjectExpression) {
2323
if (!configArg.properties.some(p => isProperty(p) && isIdentifier(p.key) && p.key.name === 'defaultValue')) {
2424
context.report({
2525
messageId: 'forbidden',
@@ -28,6 +28,16 @@ export const noIgnoredDefaultValueRule = ruleCreator({
2828
}
2929
}
3030

31+
function checkConfigType(configArg: es.Node) {
32+
const configArgType = getType(configArg);
33+
if (!configArgType?.getProperties().some(p => p.name === 'defaultValue')) {
34+
context.report({
35+
messageId: 'forbidden',
36+
node: configArg,
37+
});
38+
}
39+
}
40+
3141
function checkFunctionArgs(callExpression: es.CallExpression, reportNode: es.Node) {
3242
const scope = context.sourceCode.getScope(callExpression);
3343
if (!isImport(scope, 'firstValueFrom', /^rxjs\/?/)
@@ -49,10 +59,17 @@ export const noIgnoredDefaultValueRule = ruleCreator({
4959
});
5060
return;
5161
}
62+
if (isIdentifier(configArg)) {
63+
checkConfigType(configArg);
64+
return;
65+
} else if (isMemberExpression(configArg) && isIdentifier(configArg.property)) {
66+
checkConfigType(configArg.property);
67+
return;
68+
}
5269
if (!isObjectExpression(configArg)) {
5370
return;
5471
}
55-
checkConfig(configArg);
72+
checkConfigObj(configArg);
5673
}
5774

5875
function checkOperatorArgs(callExpression: es.CallExpression, reportNode: es.Node) {
@@ -71,10 +88,17 @@ export const noIgnoredDefaultValueRule = ruleCreator({
7188
return;
7289
}
7390
const [arg] = args;
91+
if (isIdentifier(arg)) {
92+
checkConfigType(arg);
93+
return;
94+
} else if (isMemberExpression(arg) && isIdentifier(arg.property)) {
95+
checkConfigType(arg.property);
96+
return;
97+
}
7498
if (!isObjectExpression(arg)) {
7599
return;
76100
}
77-
checkConfig(arg);
101+
checkConfigObj(arg);
78102
}
79103

80104
return {

tests/rules/no-ignored-default-value.test.ts

Lines changed: 34 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -12,6 +12,14 @@ ruleTester({ types: true }).run('no-ignored-default-value', noIgnoredDefaultValu
1212
firstValueFrom(of(42), { defaultValue: 0 });
1313
firstValueFrom(of(42), { defaultValue: null });
1414
firstValueFrom(of(42), { defaultValue: undefined });
15+
function getValue(obs) {
16+
return firstValueFrom(obs, { defaultValue: "hello" });
17+
}
18+
class Foo {
19+
getValue(obs) {
20+
return firstValueFrom(obs, { defaultValue: "world" });
21+
}
22+
}
1523
`,
1624
stripIndent`
1725
// lastValueFrom with default value
@@ -37,12 +45,24 @@ ruleTester({ types: true }).run('no-ignored-default-value', noIgnoredDefaultValu
3745
of(42).pipe(last(x => x, { defaultValue: null }));
3846
of(42).pipe(last(x => x, { defaultValue: undefined }));
3947
`,
48+
stripIndent`
49+
// other operators
50+
import { of, map, filter, refCount } from "rxjs";
51+
52+
of(42).pipe(map(x => x), filter(x => x > 0), shareReplay({ bufferSize: 1, refCount: true }));
53+
`,
4054
stripIndent`
4155
// non-RxJS firstValueFrom
4256
import { of } from "rxjs";
4357
4458
function firstValueFrom(obs) {}
4559
firstValueFrom(of(42));
60+
61+
class Foo {
62+
firstValueFrom(obs) {}
63+
}
64+
const myFoo = new Foo();
65+
myFoo.firstValueFrom(of(42));
4666
`,
4767
stripIndent`
4868
// non-RxJS lastValueFrom
@@ -76,6 +96,12 @@ ruleTester({ types: true }).run('no-ignored-default-value', noIgnoredDefaultValu
7696
~~~~~~~~~~~~~~ [forbidden]
7797
firstValueFrom(of(42), {});
7898
~~ [forbidden]
99+
const config = {};
100+
firstValueFrom(of(42), config);
101+
~~~~~~ [forbidden]
102+
const config2 = { config: {} };
103+
firstValueFrom(of(42), config2.config);
104+
~~~~~~ [forbidden]
79105
`,
80106
),
81107
fromFixture(
@@ -94,6 +120,14 @@ ruleTester({ types: true }).run('no-ignored-default-value', noIgnoredDefaultValu
94120
95121
of(42).pipe(first());
96122
~~~~~ [forbidden]
123+
of(42).pipe(first({}));
124+
~~ [forbidden]
125+
const config = {};
126+
of(42).pipe(first(config));
127+
~~~~~~ [forbidden]
128+
const config2 = { config: {} };
129+
of(42).pipe(first(config2.config));
130+
~~~~~~ [forbidden]
97131
`,
98132
),
99133
fromFixture(

0 commit comments

Comments
 (0)