Platform: Improve the type safety of select()

Created on 16 Aug 2019  路  9Comments  路  Source: ngrx/platform

It would be nice if

this.store.pipe(select('someProperty'))

would throw a compile error if someProperty does not exist in the state defined.
Currently, it always falls back to this signature
https://github.com/ngrx/platform/blob/214e7dc3080ec81afff29140882a695db22cc129/modules/store/src/store.ts#L178-L185

If accepted, I would be willing to submit a PR for this feature

[x] Yes (Assistance is provided if you need help submitting a pull request)
[ ] No

Accepting PRs Store community watch

Most helpful comment

For me, string selectors are the "worst" selectors there are.
I encourage selectors, but for small project this might be an overkill and I would fallback to:

store.select(state => state.some.property)

All 9 comments

Do you want to create a PR for this @macjohnny ?

@timdeschryver i will try to investigate this and find a solution

Will you add some context as to why you are using string selectors instead of selector functions?

@brandonroberts sometimes it is handy to just select a single property with

interface State {
  some: {
    property: number;
  }
}

@Component()
export class MyComponent {
  someProperty$: Observable<number> = this.store$.pipe(select('some', 'property'));
  someProperty2$: Observable<number> = this.store$.select('some', 'property');

  constructor(private store$: Store<State>) {}
}

without needing to declare a selector function for every single, possibly nested property of the state.
the function signatures
https://github.com/ngrx/platform/blob/214e7dc3080ec81afff29140882a695db22cc129/modules/store/src/store.ts#L122-L177
allow do to that, but unfortunately, the compiler will fall back to
https://github.com/ngrx/platform/blob/214e7dc3080ec81afff29140882a695db22cc129/modules/store/src/store.ts#L178-L185
in any case, preventing the overloading definitions from ensuring type-safety.

or is this pattern discouraged?

moreover, it is a bit more compact than

someProperty$: Observable<number> = this.store$.pipe(
  map(state => state.some && state.some.property),
  distinctUntilChanged()
)

For me, string selectors are the "worst" selectors there are.
I encourage selectors, but for small project this might be an overkill and I would fallback to:

store.select(state => state.some.property)

@timdeschryver so do you want me to close the issue and PR?

I agree with @timdeschryver, that's why I asked for more context. I'd recommend using selector functions even for "simple" selections.

Imho, if we support strings as selectors, the correct typings should be provided (if possible).

@timdeschryver I agree that the correct typings should be provided, as the function accepts string selectors.

Was this page helpful?
0 / 5 - 0 ratings