-
-
Notifications
You must be signed in to change notification settings - Fork 1.2k
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 PayloadAction inference #138
Conversation
By wrapping the match in a single-element tuple, it prevents the conditional from being checked distributively, which otherwise has the effect of converting a union into an intersection when used with contra-variant types.
Deploy preview for redux-starter-kit-docs ready! Built with commit 9c7ac4e https://deploy-preview-138--redux-starter-kit-docs.netlify.com |
I'll similarly ask for help on this one. You think it's worth merging / ready to merge? |
Looks like @denisw may have more context here. I'll take some more time to look over this tonight if he's not available, though. |
I didn't know about distributive conditional types - thanks for the pointer! The PR looks good to me. The only thing I'd add is a comment at the definition of |
Cheers, @denisw. I didn't know about distributive conditionals either until I ran into this and wanted to figure out what was happening. Does anyone have an explanatory comment in mind? I'm thinking something appended to the bottom of
I'll commit and push this if there are no objections. |
Sure, seems good. (I still don't quite grok the meaning, but sounds plausible :) ) |
Thank you for this library, it really improves the workflow with redux. I am currently using it on a react typescript project for a short time, but can already see the benefit. 👏 I ran into the same issue as @kroogs with the first reducer I wrote using createSlice. Slice instance looks like this:
Trying to dispatch that action from outside resulted with error: This is code in the container:
I just modified the dist node_modules for the time being as this PR fixes the problem (thank you @kroogs !), but it's only a temporary solution. Is this PR ready to be merged? If not, what can we do to improve it? |
As perhaps an alternate way of reaching the same end, perhaps: // Since TS only distributes conditionals when the checked type is a naked type parameter
// intersecting with an empty interface will prevent it from distributing, without changing the contract of T
type NoDistribute<T> = T & {};
export type SliceActionCreator<P> = NoDistribute<P> extends void ? //... If you wanted to link the docs on distributive conditional types for context in the comment, they're here: https://www.typescriptlang.org/docs/handbook/advanced-types.html#distributive-conditional-types. |
In the absence of further comments, I'm going to assume this is okay and go with it. |
By wrapping the
P
match inSliceActionCreator<P>
with a single-element tuple, it prevents the conditional from being checked distributively, which otherwise has the effect of converting a union into an intersection when used with contra-variant types.Without this change, the modified test emits the following error:
Argument of type '2' is not assignable to parameter of type 'number & number[]'. Type '2' is not assignable to type 'number[]'.
Argument of type 'number[]' is not assignable to parameter of type 'number & number[]'. Type 'number[]' is not assignable to type 'number'.
My original two comments on this issue are here: #133 (comment) and here: #133 (comment). More information about distributive conditionals can be found here: https://www.typescriptlang.org/docs/handbook/release-notes/typescript-2-8.html. They're very useful and typically match our intent when combining unions with other types, but in cases like these they end up transforming the resulting type into something entirely useless.