@@ -67,6 +67,33 @@ ruleTester({ types: true }).run('no-misused-observables', noMisusedObservablesRu
6767 languageOptions : { parserOptions : { ecmaFeatures : { jsx : true } } } ,
6868 } ,
6969 // #endregion valid; void return attribute
70+ // #region valid; void return inherited method
71+ {
72+ code : stripIndent `
73+ // void return inherited method; explicitly allowed
74+ import { Observable, of } from "rxjs";
75+
76+ class Foo {
77+ foo(): void {}
78+ }
79+
80+ class Bar extends Foo {
81+ foo(): Observable<number> { return of(42); }
82+ }
83+ ` ,
84+ options : [ { checksVoidReturn : false } ] ,
85+ } ,
86+ stripIndent `
87+ // void return inherited method; unrelated
88+ class Foo {
89+ foo(): void {}
90+ }
91+
92+ class Bar extends Foo {
93+ foo(): number { return 42; }
94+ }
95+ ` ,
96+ // #endregion valid; void return inherited method
7097 // #region valid; spread
7198 {
7299 code : stripIndent `
@@ -170,6 +197,151 @@ ruleTester({ types: true }).run('no-misused-observables', noMisusedObservablesRu
170197 } ,
171198 ) ,
172199 // #endregion invalid; void return attribute
200+ // #region invalid; void return inherited method
201+ fromFixture (
202+ stripIndent `
203+ // void return inherited method; class declaration; extends
204+ import { Observable, of } from "rxjs";
205+
206+ class Foo {
207+ foo(): void {}
208+ }
209+
210+ class Bar extends Foo {
211+ foo(): Observable<number> { return of(42); }
212+ ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ [forbiddenVoidReturnInheritedMethod { "heritageTypeName": "Foo" }]
213+ }
214+ ` ,
215+ ) ,
216+ fromFixture (
217+ stripIndent `
218+ // void return inherited method; class declaration; abstract extends
219+ import { Observable } from "rxjs";
220+
221+ class Foo {
222+ foo(): void {}
223+ }
224+
225+ abstract class Bar extends Foo {
226+ abstract foo(): Observable<number>;
227+ ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ [forbiddenVoidReturnInheritedMethod { "heritageTypeName": "Foo" }]
228+ }
229+ ` ,
230+ ) ,
231+ fromFixture (
232+ stripIndent `
233+ // void return inherited method; class declaration; extends abstract
234+ import { Observable, of } from "rxjs";
235+
236+ abstract class Foo {
237+ abstract foo(): void;
238+ }
239+
240+ class Bar extends Foo {
241+ foo(): Observable<number> { return of(42); }
242+ ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ [forbiddenVoidReturnInheritedMethod { "heritageTypeName": "Foo" }]
243+ }
244+ ` ,
245+ ) ,
246+ fromFixture (
247+ stripIndent `
248+ // void return inherited method; class declaration; abstract extends abstract
249+ import { Observable } from "rxjs";
250+
251+ abstract class Foo {
252+ abstract foo(): void;
253+ }
254+
255+ abstract class Bar extends Foo {
256+ abstract foo(): Observable<number>;
257+ ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ [forbiddenVoidReturnInheritedMethod { "heritageTypeName": "Foo" }]
258+ }
259+ ` ,
260+ ) ,
261+ fromFixture (
262+ stripIndent `
263+ // void return inherited method; class declaration; implements
264+ import { Observable, of } from "rxjs";
265+
266+ interface Foo {
267+ foo(): void;
268+ }
269+
270+ class Bar implements Foo {
271+ foo(): Observable<number> { return of(42); }
272+ ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ [forbiddenVoidReturnInheritedMethod { "heritageTypeName": "Foo" }]
273+ }
274+ ` ,
275+ ) ,
276+ fromFixture (
277+ stripIndent `
278+ // void return inherited method; class declaration; abstract implements
279+ import { Observable } from "rxjs";
280+
281+ interface Foo {
282+ foo(): void;
283+ }
284+
285+ abstract class Bar implements Foo {
286+ abstract foo(): Observable<number>;
287+ ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ [forbiddenVoidReturnInheritedMethod { "heritageTypeName": "Foo" }]
288+ }
289+ ` ,
290+ ) ,
291+ fromFixture (
292+ stripIndent `
293+ // void return inherited method; class declaration; implements type intersection
294+ import { Observable, of } from "rxjs";
295+
296+ type Foo = { foo(): void } & { bar(): void };
297+
298+ class Bar implements Foo {
299+ foo(): Observable<number> { return of(42); }
300+ ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ [forbiddenVoidReturnInheritedMethod { "heritageTypeName": "Foo" }]
301+ bar(): void {}
302+ }
303+ ` ,
304+ ) ,
305+ fromFixture (
306+ stripIndent `
307+ // void return inherited method; class declaration; extends and implements
308+ import { Observable, of } from "rxjs";
309+
310+ interface Foo {
311+ foo(): Observable<void>;
312+ }
313+
314+ interface Bar {
315+ foo(): void;
316+ }
317+
318+ class Baz {
319+ foo(): void {}
320+ }
321+
322+ class Qux extends Baz implements Foo, Bar {
323+ foo(): Observable<void> { return of(42); }
324+ ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ [forbiddenVoidReturnInheritedMethod { "heritageTypeName": "Baz" }]
325+ ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ [forbiddenVoidReturnInheritedMethod { "heritageTypeName": "Bar" }]
326+ }
327+ ` ,
328+ ) ,
329+ fromFixture (
330+ stripIndent `
331+ // void return inherited method; class declaration; extends class expression
332+ import { Observable, of } from "rxjs";
333+
334+ const Foo = class {
335+ foo(): void {}
336+ }
337+
338+ class Bar extends Foo {
339+ foo(): Observable<number> { return of(42); }
340+ ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ [forbiddenVoidReturnInheritedMethod { "heritageTypeName": "Foo" }]
341+ }
342+ ` ,
343+ ) ,
344+ // #endregion invalid; void return inherited method
173345 // #region invalid; spread
174346 fromFixture (
175347 stripIndent `
0 commit comments