Skip to content
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

Fix #212 #214 #215

Merged
merged 4 commits into from
Oct 16, 2019
Merged
Show file tree
Hide file tree
Changes from 3 commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
4 changes: 2 additions & 2 deletions src/createSlice.ts
Original file line number Diff line number Diff line change
Expand Up @@ -73,7 +73,7 @@ export interface CreateSliceOptions<
* functions. These reducers should have existing action types used
* as the keys, and action creators will _not_ be generated.
*/
extraReducers?: CaseReducers<State, any>
extraReducers?: CaseReducers<NoInfer<State>, any>
}

type PayloadActions<Types extends keyof any = string> = Record<
Expand Down Expand Up @@ -230,7 +230,7 @@ export function createSlice<
})

const finalCaseReducers = { ...extraReducers, ...sliceCaseReducersByType }
const reducer = createReducer(initialState, finalCaseReducers)
const reducer = createReducer(initialState, finalCaseReducers as any)

return {
name,
Expand Down
10 changes: 3 additions & 7 deletions src/tsHelpers.ts
Original file line number Diff line number Diff line change
Expand Up @@ -13,8 +13,8 @@ export type IsUnknown<T, True, False = never> = unknown extends T
: False

export type IsEmptyObj<T, True, False = never> = T extends any
Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This is what I'm most concerned with. I believe this should be good to find really empty objects (the one before also matched objects with only optional properties), but I'm not 100% sure I'm not missing something.

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Your intuition is right! As far as I know, that's the most reliable way to match an empty object. {} is very tricky, since it doesn't really mean empty object. 😉

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Thanks a lot, that gives me some assurance :)

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

The empty object detection looks good to me too. keyof T extends never is the most reliable way to ensure that the type has no keys.

? {} extends T
? IsUnknown<T, False, IsAny<T, False, True>>
? keyof T extends never
? IsUnknown<T, False, True>
: False
: never

Expand All @@ -24,11 +24,7 @@ export type IsEmptyObj<T, True, False = never> = T extends any
* * versions below 3.5 will return `{}` for unresolvable interference
* * versions above will return `unknown`
* */
export type AtLeastTS35<True, False> = IsUnknown<
ReturnType<<T>() => T>,
True,
False
>
export type AtLeastTS35<True, False> = [True, False][IsUnknown<ReturnType<<T>() => T>, 0, 1>]

export type IsUnknownOrNonInferrable<T, True, False> = AtLeastTS35<
IsUnknown<T, True, False>,
Expand Down
13 changes: 13 additions & 0 deletions type-tests/files/createAction.typetest.ts
Original file line number Diff line number Diff line change
Expand Up @@ -172,3 +172,16 @@ function expectType<T>(p: T): T {
// typings:expect-error
expectType<string>(strLenMetaAction('test').meta)
}

/*
* regression test for https://github.com/reduxjs/redux-starter-kit/issues/214
*/
{
const action = createAction<{ input?: string }>('ACTION')
const t: string|undefined = action({input: ""}).payload.input;

// typings:expect-error
const u: number = action({input: ""}).payload.input;
// typings:expect-error
const v: number = action({input: 3}).payload.input;
}