We have been using redux since nearly two years and refactored full time a legacy application for about a year.
With your approach I’d say, you should not use redux. Redux implements the flux approach, and if your logic is not in the reducers and selectors, it’s not part of the unidirectional flux flow.
I’m not saying your approach is bad, but the way you use redux it’s only adds overhead which you are abstracting away. So why use it?
The idea of redux is, that your business logic is in the reducers and selectors. Action creators should be very simple, not contain any logic. Sagas help with that, containing the asynchronous parts.
This results in actions that clearly communicate what happened in the application, which is useful (originally, it says actions are intend, but the action Dispatcher might not know the final intend, an action for what happened is often better).
It results in business logic that is contained in pure functions, which are easy and fast to test.
Properly using redux also means great tooling. If I interact with the app and see misbehaviour, I have one action in the Dev tools related to that, I see what that changed the state and I can search in the codebase for the action type and find all sagas, reducers and the one Dispatcher (connected component) of the action. That’s a benefit you loose when generation your action types. And if your want to introduce a new action type, you can make a quick search if it already exists. If there are many clashes, your actions are too generic. You should not reuse actions, because they should not contain logic.
If you just want crud, you can make some kind of DTOs provided by a singleton which can be listened to. You don’t need reducers or actions at all then.