-
-
Notifications
You must be signed in to change notification settings - Fork 2k
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
feat(store): use variadic tuple types for createSelector #3023
feat(store): use variadic tuple types for createSelector #3023
Conversation
/** | ||
* @deprecated Selectors with props are deprecated, for more info see {@link https://github.com/ngrx/platform/issues/2980 Github Issue} | ||
*/ | ||
export function createSelector<State, Props, S1, Result>( |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
left the existing definitions for createSelector
when creating selectors with props since it's deprecated and will eventually be removed
Preview docs changes for 41df527 at https://previews.ngrx.io/pr3023-41df527a/ |
The example-app tests are failing on circleci and yet "it works on my machine" the error complains about
|
Does that error disappears if you remove the deprecated selector with props? |
0dc1ca4
to
c53a8d4
Compare
Since there can be minor type adjustments that are breaking, it may be best to pair this with a pr that completely removes |
So it all works now, but in some circumstances (as evidenced by the few changes to other files) the overloads are not properly recognized if the projector functions have explicitly typed parameters. Not sure why and if anyone has advanced TS knowledge to avoid this as to not make this a breaking change, that'd be litty. |
985578f
to
53fd1cd
Compare
Is this dependent on selectors with props being removed? If so, I say we close it until then. |
This is not dependent on selectors with props being removed. |
Since the types in some tests are changed, I think this will lead to some breaking changes? |
Right now it's a breaking change, but I'm pretty sure there's something that could be done either with the types or with a Typescript issue that would cause the overloads to not be improperly interpreted... if someone smarter than me could find a solution 😅. |
08b00f3
to
3265126
Compare
@timdeschryver This is a breaking change because you cannot provide a specific set of generic type arguments to So |
@@ -1,7 +1,7 @@ | |||
import { createSelector } from '@ngrx/store'; | |||
import { Stories, Story } from './story'; | |||
|
|||
export const selectStories = createSelector<Story[], Story[], Story[][]>( | |||
export const selectStories = createSelector<Story[], [Story[]], Story[][]>( |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Explicitly provided generic arguments must take the format <State, [S1, S2, Etc], Result>
@timdeschryver Seems like v13 of Angular is approaching, and it seems since the last NGRX v12 release you've started deprecating features in master, so I guess we're gearing up for NGRX v13 too? |
@MaximSagan we're not there yet. |
@timdeschryver Is this planned for v13? I noticed it wasn't included for the first beta. |
@brandonroberts Wondering if there is a blocker for this being included in v13? |
@david-shortman no blocker. I wasn't sure if this was ready to be merged yet |
@brandonroberts It should be. I'm not sure why it doesn't have any reviews yet, but it is ready. |
dd49aef
to
4cabfa1
Compare
Sorry for my late response, I can take a look at it later this week and provide some feedback then. |
@timdeschryver thanks! Also, I've created a PR dependent on this one, #3223, which offers a gentle path through depreciation to move towards a strongly-typed |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
This looks good to me.
We could also provide a schematic that provides a fix for the breaking change, e.g.
BEFORE:
createSelector<Story[], Story[], Story[][]>
AFTER:
// needs to be a tuple 👇
createSelector<Story[], [ Story[] ] , Story[][]>
I haven't written a schematic before, but it could be fun to try. Should I go for that in a separate PR? |
@david-shortman @timdeschryver is the tuple only required when you strictly define all the types with |
The generic arguments are inferred, so that you can use When manually specifying the generic arguments, you have to specify the selector's list of selector return values, like |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Great work David! 🥇
Btw, it would be great to add type tests for selectors :)
modules/store/src/selector.ts
Outdated
export function createSelector<State, S1, Result>( | ||
s1: Selector<State, S1>, | ||
projector: (s1: S1) => Result | ||
export function createSelector<State, S extends unknown[], Result>( |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
It would be great to give a meaningful name to the S
generic because it's not clear at first what is its purpose. The name could be: Slices
s1: Selector<State, S1>, | ||
projector: (s1: S1) => Result | ||
export function createSelector<State, S extends unknown[], Result>( | ||
...args: [...Selector<State, unknown>[], unknown] & |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
nice hack 👀
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
🙇♂️
modules/store/src/selector.ts
Outdated
props: Props | ||
) => Result | ||
): MemoizedSelectorWithProps<State, Props, Result>; | ||
export function createSelector<State, S1, S2, S3, S4, S5, S6, S7, Result>( | ||
|
||
export function createSelector<State, S extends unknown[], Result>( |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
the same here: S
=> Slices
I think ts-snippet can only validate the return type of the function, not whether the function inferred the parameters correctly. In #3223, the return type is validated in type checks since the |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
LGTM 👍
Changed PR type from
|
🥳 |
PR Checklist
Please check if your PR fulfills the following requirements:
PR Type
What kind of change does this PR introduce?
What is the current behavior?
Types were manually created for set numbers of arguments.
Completes #2715 (I don't see any reducer code that still needs variadic typing?)
What is the new behavior?
createSelector
stays strongly typed for an infinite number of arguments.Does this PR introduce a breaking change?
Some small typing adjustments.