-
-
Notifications
You must be signed in to change notification settings - Fork 1.6k
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
Improve type definition of create
to accept CustomSetState
#428
Conversation
This pull request is automatically built and testable in CodeSandbox. To see build info of the built libraries, click here or the icon next to each commit SHA. Latest deployment of this branch, based on commit 4aa50f1:
|
Hi, thanks for your work! This looks like a good improvement. Does this solve some existing issues? I haven't looked into details yet, but I think we should keep the JS bundle size. Just added a commit to update the size snapshot. Can you change it to make changes only in TS? |
Hello! Yes, my issue is going to be solved. Sure thing! Some of my extra nit pick makes size up. I'll fix it. |
I confirmed now the JS bundle size is as it was. 👍 |
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.
Bundle size is good now. Please check two comments.
typeof partial === 'function' | ||
? (partial as (state: TState) => TState)(state) | ||
: partial | ||
const nextState = typeof partial === 'function' ? partial(state) : partial |
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.
Hm, so we can remove the type assertion because of this PR, or was it already possible with the previous one?
Either way, let's remove L71-L72 comments.
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.
Ah, sorry my fix was sloppy it wasn't revert correctly but... it work okay. Sure, gonna remove comments.
src/vanilla.ts
Outdated
@@ -109,6 +119,7 @@ export default function create<TState extends State>( | |||
|
|||
const destroy: Destroy = () => listeners.clear() | |||
const api = { setState, getState, subscribe, destroy } | |||
state = createState(setState, getState, api) | |||
// SetState<TState> includes CustomSetState so it should be ok |
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.
Can we do something like this?
diff --git a/src/vanilla.ts b/src/vanilla.ts
index ed33bc2..38d1fd7 100644
--- a/src/vanilla.ts
+++ b/src/vanilla.ts
@@ -62,7 +62,7 @@ export type StateCreator<T extends State, CustomSetState = SetState<T>> = (
export default function create<
TState extends State,
- CustomSetState = SetState<TState>
+ CustomSetState extends SetState<TState> = SetState<TState>
>(createState: StateCreator<TState, CustomSetState>): StoreApi<TState> {
let state: TState
const listeners: Set<StateListener<TState>> = new Set()
@@ -119,7 +119,6 @@ export default function create<
const destroy: Destroy = () => listeners.clear()
const api = { setState, getState, subscribe, destroy }
- // SetState<TState> includes CustomSetState so it should be ok
- state = createState(setState as any as CustomSetState, getState, api)
+ state = createState(setState as CustomSetState, getState, api)
return api
}
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.
Ahh,I should have figure it out before using any
... Thank you for good catch!
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.
Hm, like a test I added, I'd like to apply a CustomSetState
that set a different type of state.
In a example, set
cannot update readA/B
because the second argument is SetState<Pick<ExampleState, 'a' | 'b'>>
. However, Pick<ExampleState, 'a' | 'b'>
couldn't satisfies TState
...
CustomSetState extends SetState<any> = SetState<TState>
is going to fix setState as any as CustomSetState
but test passes. I'll send a patch for your check.
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.
Yeah, that's something I was concerned. Maybe this can't be helped.
SetState includes CustomSetState
I'm not sure if I understand this...
Not related, but linking #441. |
src/vanilla.ts
Outdated
): StoreApi<TState> { | ||
export default function create< | ||
TState extends State, | ||
CustomSetState extends SetState<any> = SetState<TState> |
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.
I'm not sure what this any
would cause. It could cause runtime error without compile error, technically?
@TkDodo can you review this PR please?
@hachibeeDI |
Let me hold on this PR. |
My big apologies about adding some commits without any success. We should probably start over. |
Motivation
I was creating a middleware which returns
StateCreator<State, CustomSetState>
but it was denied becausecreate
is not acceptCustomSetState
as a second type argument.Bonus
As you noticed, I modified a test "can set the store without merging" in
basic.test.tsx
.Previously
StateCreator
couldn't infer the state correctly so that store was inferred as object.But now it is as it should so we need let TypeScript compiler knows that keys
a
andb
are possibly undefined.Thanks!