-
Notifications
You must be signed in to change notification settings - Fork 59
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
Use optional type instead of dynamic for actions #77
Comments
The reason we use Therefore, this would be breaking change and a significant one at that. It's something we considered early on, but we chose not to go with a typed action because many middleware packages need to dispatch custom actions, which would not work in a typed-generic world. |
|
For sure -- there are pros and cons to allowing and not allowing generics :) It's been a while since we considered the topic. Happy to leave it open for a bit to hear from more folks if they're interested! |
Just a datapoint - we do not use a parent class for any of our actions when using Redux in Flutter. We do in Angular, but that's because we need all our actions to have a I can't think of a use case where all actions would have some shared functionality where we would require extending from a base class. Unless you're using some uber AppAction that handles everything, but I'd consider that an anti pattern and what you should be doing is having many, single purpose actions. It's not just middleware this would cause problems with, but also libraries like in redux_entity. I'm not sure it would be possible to use redux_entity in a project that enforced a base class for actions. I'm also not sure that an assert to ensure the type of the base class is a good idea. What you want your reducer to do, in the case of an unknown action, is to NOP and just return the state unchanged. That way your reducer won't break if the app changes and new kinds of actions flow through the store. tl;dr - I can't think of a practical benefit this would bring for how we are using redux, and would cause problems for packages. |
Could it be |
Having an Yes, middlewares complicate things:
But these problems are surely worth solving - the payoff is that dispatching an action can be type checked, so you can actually reason about what actions flow through the store. At the moment there's nothing stopping you from dispatching an action that isn't handled by the reducers (including by ignoring it...), and no help in the reducer type to understand what the Seems like part of the problem is the lack of union types in Dart (see dart-lang/language#83) - which makes it hard to say that an action could be |
I agree that dynamic is bad thing. So I created a new typed redux packages for the Maybe it will help to anybody else : ) |
Proposal
It'd be great if
Store
had another generic type to be used as theaction
argument type in methods likedispatch
, preventing non-action objects from being used as actions.This should be non-breaking for most users, as type inference should allow
Store
constructors to omit the existing state type, and the addition of another type will only break invocations that specify it explicitly.Reasoning
I've separated my project into layers, like so:
Data:
project_data
: Platform-agnostic repository implementationsDomain:
project_domain
: Core platform-agnostic functionality, including state managementPlatform:
project_flutter
: A GUI using Flutterproject_cli
: A CLIPlatform implementations can build a Redux store with a
buildStore
function in the domain package, passing in repository implementations to use. The domain package exports different action classes that the platform implementation can dispatch to the store. Each action class extends from an internal (non-exported)AppAction
class.If the
dispatch
function only acceptsAppAction
subtypes, this will prevent non-action objects being used by the platform implementations, requiring all actions to be used from the domain package.Workarounds
At the moment, an assert can be used, but this throws an error at runtime. A compilation error is preferred.
The text was updated successfully, but these errors were encountered: