-
Notifications
You must be signed in to change notification settings - Fork 30.5k
Description
Trying to use react-redux's connect
as a class decorator can cause error messages of the form Type 'foo' is not assignable to type 'void'
. The issue with these typings seems to be that TypeScript doesn't allow ClassDecorator
s to change the signature of the thing that they decorate, but this is the current implementation of the react-redux typings and is done purposefully, since react-redux returns a different instance with a different signature for the props.
Using connect
as a function works as expected; it's only the usage as a decorator that causes type problems.
Suggestions are welcome, but any proposed solutions should be a strict improvement on what the typings can currently express, which is to say, sacrificing the current correctness of the usage-as-a-function typings is not acceptable (partly because that would be a severe regression and partly because decorators are deemed "experimental" and therefore, I assert, secondary to standard function usage).
I don't know that a complete solution to the decorator-typing problem is possible while microsoft/TypeScript#4881 is outstanding. That said, there are incremental improvements in this case, such as by (first pass) outputting any kind of React.ComponentClass
so the code at least compiles, then (second pass) outputting a component that accepts the intersection of all the props (own as well as connected), even though that would be too lenient, so the code type checks at least some of the props.
The only workaround I have right now is to not use connect
as a decorator. Some may find it ugly stylistically, but it type-checks correctly, isn't any lengthier and is usable in more places than a decorator.
Instead of:
@connect(mapStateToProps, mapDispatchToProps)
class MyComponent extends React.Component<...> { ... <
668D
span class="pl-kos">}
use (something along the lines of):
class MyComponentImpl extends React.Component<...> { ... }
const MyComponent = connect(mapStateToProps, mapDispatchToProps)(MyComponentImpl);
Note that #8787 comes into play here and is sometimes conflated with this issue. You may also want a type hint or a cast to make sure the output component has the proper type.
Edit: microsoft/TypeScript#12114 may help with this case: the decorator could potentially be written to create an all-optional version of the props for the generated component, which isn't totally ideal but continues to let your implementation be more assertive about prop nullity.