Skip to content

Commit

Permalink
Merge pull request #529 from reduxjs/intersection-GetStateFromSelectors
Browse files Browse the repository at this point in the history
  • Loading branch information
markerikson authored Oct 26, 2021
2 parents e71ab31 + 9240c41 commit 1a338f5
Show file tree
Hide file tree
Showing 2 changed files with 46 additions and 8 deletions.
15 changes: 7 additions & 8 deletions src/types.ts
Original file line number Diff line number Diff line change
Expand Up @@ -37,15 +37,14 @@ type GetStateFromSelector<S> = S extends Selector<infer State> ? State : never
export type GetStateFromSelectors<S extends SelectorArray> =
// handle two elements at once so this type works for up to 30 selectors
S extends [infer C1, infer C2, ...infer Other]
? Other extends SelectorArray
?
| GetStateFromSelector<C1>
| GetStateFromSelector<C2>
| GetStateFromSelectors<Other>
: GetStateFromSelector<C1> | GetStateFromSelector<C2>
? Other extends [any]
? GetStateFromSelector<C1> &
GetStateFromSelector<C2> &
GetStateFromSelectors<Other>
: GetStateFromSelector<C1> & GetStateFromSelector<C2>
: S extends [infer Current, ...infer Other]
? Other extends SelectorArray
? GetStateFromSelector<Current> | GetStateFromSelectors<Other>
? Other extends [any]
? GetStateFromSelector<Current> & GetStateFromSelectors<Other>
: GetStateFromSelector<Current>
: S extends (infer Elem)[]
? GetStateFromSelector<Elem>
Expand Down
39 changes: 39 additions & 0 deletions typescript_test/test.ts
Original file line number Diff line number Diff line change
Expand Up @@ -1060,8 +1060,47 @@ type SelectorArray29 = [
(_state: StateA) => 29
]

// Ensure that input functions with mismatched states raise errors
type Results = SelectorResultArray<SelectorArray29>
type State = GetStateFromSelectors<SelectorArray29>

{
const selector = createSelector(
(state: string) => 1,
(state: number) => 2,
(...args) => 0
)
// @ts-expect-error
selector('foo')
// @ts-expect-error
selector(5)
}
{
const selector = createSelector(
(state: { foo: string }) => 1,
(state: { bar: string }) => 2,
(...args) => 0
)
selector({ foo: '', bar: '' })
// @ts-expect-error
selector({ foo: '' })
// @ts-expect-error
selector({ bar: '' })
}

{
const selector = createSelector(
(state: { foo: string }) => 1,
(state: { foo: string }) => 2,
(...args) => 0
)
// @ts-expect-error
selector({ foo: '', bar: '' })
selector({ foo: '' })
// @ts-expect-error
selector({ bar: '' })
}

// Issue #526
function testInputSelectorWithUndefinedReturn() {
type Input = { field: number | undefined }
Expand Down

0 comments on commit 1a338f5

Please sign in to comment.