Skip to content

Commit

Permalink
Merge branch 'master' into intersection-GetStateFromSelectors
Browse files Browse the repository at this point in the history
# Conflicts:
#	typescript_test/test.ts
  • Loading branch information
markerikson committed Oct 26, 2021
2 parents 5fb31d7 + e71ab31 commit 9240c41
Show file tree
Hide file tree
Showing 3 changed files with 116 additions and 70 deletions.
5 changes: 3 additions & 2 deletions .eslintrc
Original file line number Diff line number Diff line change
Expand Up @@ -54,7 +54,7 @@
}
},
{
"files": ["**/test/**/*.ts"],
"files": ["**/test/**/*.ts", "**/typescript_test/**/*.ts"],
"rules": {
"consistent-return": "off",
"max-lines": "off",
Expand All @@ -67,7 +67,8 @@
"@typescript-eslint/no-unused-vars": "off",
"@typescript-eslint/camelcase": "off",
"import/max-dependencies": "off",
"sonarjs/no-duplicate-string": "off"
"sonarjs/no-duplicate-string": "off",
"@typescript-eslint/no-shadow": "off"
}
}
]
Expand Down
33 changes: 23 additions & 10 deletions src/index.ts
Original file line number Diff line number Diff line change
Expand Up @@ -14,7 +14,8 @@ export type {
EqualityFn,
SelectorArray,
SelectorResultArray,
ParametricSelector
ParametricSelector,
OutputParametricSelector
} from './types'

import {
Expand Down Expand Up @@ -52,7 +53,7 @@ type DropFirst<T extends unknown[]> = T extends [unknown, ...infer U]
: never

export function createSelectorCreator<
F extends(...args: unknown[]) => unknown,
F extends (...args: unknown[]) => unknown,
MemoizeFunction extends (func: F, ...options: any[]) => F,
MemoizeOptions extends unknown[] = DropFirst<Parameters<MemoizeFunction>>
>(
Expand Down Expand Up @@ -98,7 +99,7 @@ export function createSelectorCreator<
// we wrap it in an array so we can apply it.
const finalMemoizeOptions = Array.isArray(memoizeOptions)
? memoizeOptions
: ([ memoizeOptions ] as MemoizeOptions)
: ([memoizeOptions] as MemoizeOptions)

const dependencies = getDependencies(funcs)

Expand Down Expand Up @@ -160,13 +161,25 @@ interface CreateSelectorFunction<
> {
/** Input selectors as separate inline arguments */
<Selectors extends SelectorArray, Result>(
...items:
| [...Selectors, (...args: SelectorResultArray<Selectors>) => Result]
| [
...Selectors,
(...args: SelectorResultArray<Selectors>) => Result,
CreateSelectorOptions<MemoizeOptions>
]
...items: [
...Selectors,
(...args: SelectorResultArray<Selectors>) => Result
]
): OutputSelector<
Selectors,
Result,
GetParamsFromSelectors<Selectors>,
((...args: SelectorResultArray<Selectors>) => Result) &
ReturnType<MemoizeFunction>
>

/** Input selectors as separate inline arguments with memoizeOptions passed */
<Selectors extends SelectorArray, Result>(
...items: [
...Selectors,
(...args: SelectorResultArray<Selectors>) => Result,
CreateSelectorOptions<MemoizeOptions>
]
): OutputSelector<
Selectors,
Result,
Expand Down
148 changes: 90 additions & 58 deletions typescript_test/test.ts
Original file line number Diff line number Diff line change
Expand Up @@ -164,8 +164,8 @@ function testInvalidTypeInCombinator() {

// does not allow heterogeneous parameter type
// selectors when the combinator function is typed differently
// @ts-expect-error
createSelector(
// @ts-expect-error
(state: { testString: string }) => state.testString,
(state: { testNumber: number }) => state.testNumber,
(state: { testBoolean: boolean }) => state.testBoolean,
Expand Down Expand Up @@ -994,70 +994,73 @@ function createSelectorConfigOptions() {
)
}

// Verify more than 12 selectors are accepted
// Issue #525
const withLotsOfInputSelectors = createSelector(
(_state: any) => 1,
(_state: any) => 2,
(_state: any) => 3,
(_state: any) => 4,
(_state: any) => 5,
(_state: any) => 6,
(_state: any) => 7,
(_state: any) => 8,
(_state: any) => 9,
(_state: any) => 10,
(_state: any) => 11,
(_state: any) => 12,
(_state: any) => 13,
(_state: any) => 14,
(_state: any) => 15,
(_state: any) => 16,
(_state: any) => 17,
(_state: any) => 18,
(_state: any) => 19,
(_state: any) => 20,
(_state: any) => 21,
(_state: any) => 22,
(_state: any) => 23,
(_state: any) => 24,
(_state: any) => 25,
(_state: any) => 26,
(_state: any) => 27,
(_state: any) => 28,
(_state: StateA) => 1,
(_state: StateA) => 2,
(_state: StateA) => 3,
(_state: StateA) => 4,
(_state: StateA) => 5,
(_state: StateA) => 6,
(_state: StateA) => 7,
(_state: StateA) => 8,
(_state: StateA) => 9,
(_state: StateA) => 10,
(_state: StateA) => 11,
(_state: StateA) => 12,
(_state: StateA) => 13,
(_state: StateA) => 14,
(_state: StateA) => 15,
(_state: StateA) => 16,
(_state: StateA) => 17,
(_state: StateA) => 18,
(_state: StateA) => 19,
(_state: StateA) => 20,
(_state: StateA) => 21,
(_state: StateA) => 22,
(_state: StateA) => 23,
(_state: StateA) => 24,
(_state: StateA) => 25,
(_state: StateA) => 26,
(_state: StateA) => 27,
(_state: StateA) => 28,
(...args) => args.length
)

type SelectorArray29 = [
(_state: any) => 1,
(_state: any) => 2,
(_state: any) => 3,
(_state: any) => 4,
(_state: any) => 5,
(_state: any) => 6,
(_state: any) => 7,
(_state: any) => 8,
(_state: any) => 9,
(_state: any) => 10,
(_state: any) => 11,
(_state: any) => 12,
(_state: any) => 13,
(_state: any) => 14,
(_state: any) => 15,
(_state: any) => 16,
(_state: any) => 17,
(_state: any) => 18,
(_state: any) => 19,
(_state: any) => 20,
(_state: any) => 21,
(_state: any) => 22,
(_state: any) => 23,
(_state: any) => 24,
(_state: any) => 25,
(_state: any) => 26,
(_state: any) => 27,
(_state: any) => 28,
(_state: any) => 29
(_state: StateA) => 1,
(_state: StateA) => 2,
(_state: StateA) => 3,
(_state: StateA) => 4,
(_state: StateA) => 5,
(_state: StateA) => 6,
(_state: StateA) => 7,
(_state: StateA) => 8,
(_state: StateA) => 9,
(_state: StateA) => 10,
(_state: StateA) => 11,
(_state: StateA) => 12,
(_state: StateA) => 13,
(_state: StateA) => 14,
(_state: StateA) => 15,
(_state: StateA) => 16,
(_state: StateA) => 17,
(_state: StateA) => 18,
(_state: StateA) => 19,
(_state: StateA) => 20,
(_state: StateA) => 21,
(_state: StateA) => 22,
(_state: StateA) => 23,
(_state: StateA) => 24,
(_state: StateA) => 25,
(_state: StateA) => 26,
(_state: StateA) => 27,
(_state: StateA) => 28,
(_state: StateA) => 29
]

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

Expand Down Expand Up @@ -1097,3 +1100,32 @@ type State = GetStateFromSelectors<SelectorArray29>
// @ts-expect-error
selector({ bar: '' })
}

// Issue #526
function testInputSelectorWithUndefinedReturn() {
type Input = { field: number | undefined }
type Output = string
type SelectorType = (input: Input) => Output

const input = ({ field }: Input) => field
const result = (out: number | undefined): Output => 'test'

// Make sure the selector type is honored
const selector: SelectorType = createSelector(
({ field }: Input) => field,
args => 'test'
)

// even when memoizeOptions are passed
const selector2: SelectorType = createSelector(
({ field }: Input) => field,
args => 'test',
{ memoizeOptions: { maxSize: 42 } }
)

// Make sure inference of functions works...
const selector3: SelectorType = createSelector(input, result)
const selector4: SelectorType = createSelector(input, result, {
memoizeOptions: { maxSize: 42 }
})
}

0 comments on commit 9240c41

Please sign in to comment.