platform icon indicating copy to clipboard operation
platform copied to clipboard

(eslint-plugin): Propose `effect-explicit-type-parameter` ComponentStore rule

Open LayZeeDK opened this issue 9 months ago • 2 comments

Which @ngrx/* package(s) are relevant/related to the feature request?

eslint-plugin

Information

I would like to suggest/contribute a ComponentStore ESLint rule. It would be an opt-in rule as it is a stylistic choice. What do you think?

effect-explicit-type-parameter

Effect should have a type parameter.

  • Type: suggestion
  • Fixable: No
  • Suggestion: Yes
  • Requires type checking: No
  • Configurable: No

Rule Details

To have consistent code, we should explicitly add a type parameter.

Examples of incorrect code for this rule:

Arrow function with parameter type

readonly getMovie = this.effect((movieId$: Observable<string>) => {
                    // ⚠ no type parameter passed
  return movieId$.pipe(

Arrow function without parameter type

readonly getMovie = this.effect(movieId$ => {
                    // ⚠ no type parameter passed
    return movieId$.pipe(

pipe chain with parameter type

readonly getMovie = this.effect(
                    // ⚠ no type parameter passed
  pipe(
    switchMap((movieId: string) =>

pipe chain without parameter type

readonly getMovie = this.effect(
                    // ⚠ no type parameter passed
  pipe(
    switchMap(movieId =>

Examples of correct code for this rule:

Arrow function with parameter type

readonly getMovie = this.effect<string>(movieId$ => {
                    // ✅ type parameter passed
    return movieId$.pipe(

Arrow function without parameter type

readonly getMovie = this.effect<string>((movieId$: Observable<string>) => {
                    // ✅ type parameter passed
    return movieId$.pipe(

pipe chain with parameter type

readonly getMovie = this.effect<string>(
                    // ✅ type parameter passed
  pipe(
    switchMap(movieId =>

pipe chain without parameter type

readonly getMovie = this.effect<string>(
                    // ✅ type parameter passed
  pipe(
    switchMap((movieId: string) =>

Describe any alternatives/workarounds you're currently using

Without a lint rule enforcing one style, a codebase could have different variations of effect type definitions.

I would be willing to submit a PR to fix this issue

  • [x] Yes
  • [ ] No

LayZeeDK avatar Apr 11 '25 07:04 LayZeeDK

I have to disagree with this one. TypeScript can infer the generic automatically, I think using generics for this can also lead to breaking changes in the future when we want to change the types.

The default type of void also prevents accidental uses of a argument that isn't typed.

For now we also don't have stylistic rules, and I would like to keep it that way to keep things simple. All of our rules are currently applied by default, and will throw an error.

What do you think about this @markostanimirovic, @rainerhahnekamp ?

timdeschryver avatar Apr 21 '25 17:04 timdeschryver

Indeed, this is a stylistic choice. What I want to achieve is a way to make a single codebase conform to one code style.

An ideal lint rule would be configurable to choose one of these code styles:

  1. Prefer (effect) method type parameter
  2. Prefer callback parameter (argument) type annotation

With support for both arrow functions and pipe chains.

LayZeeDK avatar Apr 22 '25 09:04 LayZeeDK

Closing due to inactivity.

timdeschryver avatar Nov 30 '25 18:11 timdeschryver