Skip to content

Commit

Permalink
build intersection type instead of union type in GetStateFromSelectors
Browse files Browse the repository at this point in the history
  • Loading branch information
phryneas committed Oct 26, 2021
1 parent 4ead716 commit 5fb31d7
Show file tree
Hide file tree
Showing 2 changed files with 44 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
37 changes: 37 additions & 0 deletions typescript_test/test.ts
Original file line number Diff line number Diff line change
Expand Up @@ -1060,3 +1060,40 @@ type SelectorArray29 = [

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: '' })
}

0 comments on commit 5fb31d7

Please sign in to comment.