-
-
Notifications
You must be signed in to change notification settings - Fork 3.4k
Facilitate adding types to the dispatch
function
#1983
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
Comments
Hi. Appreciate the detailed writeup, but part of our TS usage philosophy is that we want explicit usage of TS types. Relying on overriding global ambient types is too risky and can have unexpected behavior. This is why we removed the |
Hey @markerikson, thanks for the quick response! But I'm not sure I follow. 🤔 You (the consumer) wouldn't be overriding anything at all. This wouldn't also be done in an ambient file, but instead, in a module with the Meaning that the consumers wouldn't be able to override it, they would only be able to extend it. So I'm not entirely sure what would fail here. And this type, would make it just fallback to type CustomerAction = GlobalStoreAction extends Array<infer R extends Action> ? R : AnyAction; Anyway, I completely understand if this isn't the direction that the |
The Global module augmentation is... global. And that is oftentimes bad. This starts with things like libraries. If we have this in place, it would only be natural that What if you have a monorepo, or multiple stores that have different types on server and client or in different configurations for different builds? As soon as you start augmenting, you decouple the "real runtime store" from the "TypeScript typed store". Of course, all that said, you can totally still use module augmentation in your project if you want that - but then you need to do that in your code, and you will create hooks for it (which brings you back to your starting point). You could do export interface RootState {
// will be augmented elsewhere
}
export const useAppSelector = TypedSelectorHook<RootState> |
What is the new or updated feature that you are suggesting?
MOTIVATION
Currently, the recommended method for ensuring proper typing of the
dispatch
function is to create a new hook, nameduseAppDispatch
, that is derived from the existinguseDispatch
hook. By using this new hook exclusively, you can ensure that only properly typed actions are being passed to the dispatch function.To ensure that this approach functions properly in a larger team setting, it may be necessary to implement additional measures to prevent team members from importing the original
useDispatch
hook directly. One such measure could be to create an import restriction rule using an ESLint plugin such aseslint-plugin-import-helpers
, which allows for the creation of custom helpers to restrict imports. By enforcing the use of the deriveduseAppDispatch
hook, it guarantees that all dispatched actions are properly typed.Not only that, but it seems inelegant that there is already a function that we can't somehow have "automatically typed".
SOLUTION
Since we don't want to be mixing
@reduxjs/toolkit
andreact-redux
code, it would be impossible to derive theuseDispatch
function from theconfigureStore
, which makes achieving a properly typeddispatch
function without any consumer effort infeasible.As such, my purposed solution is to rely on "typescript's module augmentation". This will allow the consumer to extend the
Action
type provided inuseDispatch
and have it automatically typed for everydispatch
use.The required implementation has ~3 steps:
1- Defining an interface that can be extended by the consumer;
2- Defining a type that parses what was passed into the interface (interfaces can't be represented by a union of members);
3- Use that interface as the
useDispatch
default generic param type;The consumer would need to:
1- Augment the empty interface with an array of their store's Action types
After that, the
dispatch
function should be automatically typed.Ts Playground of a quick implementation: playground link
Why should this feature be included?
This feature will improve the DX for typing the
dispatch
function by a lot without any breaking changes and can be done with very little effort.What docs changes are needed to explain this?
The docs about "Getting the
Dispatch
type" - the old docs could continue (as they would still be valid), but new ones could be added.The text was updated successfully, but these errors were encountered: