You signed in with another tab or window. Reload to refresh your session.You signed out in another tab or window. Reload to refresh your session.You switched accounts on another tab or window. Reload to refresh your session.Dismiss alert
{{ message }}
Repository navigation
react-redux's connect cannot be used as a decorator: type "is not assignable to type 'void'" #9951
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.
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.
changed the title [-]react-redux's `connect` cannot be used as a decorator: "type is not assignable to type 'void'"[/-][+]react-redux's `connect` cannot be used as a decorator: type "is not assignable to type 'void'"[/+]on Aug 7, 2016
I was having similar issues the other day and dropped it for the connect func. The types looked off and using old react types. I may try to fix this and submit a PR?
Of course! A lot has changed since these types were originally written, though I am still skeptical that without mutating-decorator support something useful is possible. But I've worked around other inadequacies in the type system before, so give it a shot.
Perhaps mapped types could get you part of the way there, so at least you have some useful type information in the output?
export function myConnect(mapStateToProps, mapDispatchToProps) {
return function (target) {
return <any>connect(mapStateToProps, mapDispatchToProps)(target);
}
}
Reacted by Brian Frichette, Paul Marlow, Ardy Febriansyah and dave
Reacted by Sean Kelley, Will Chen, Paulo Cesar, Miloš Kolčák, Sudhakar, BlackGanglion, cjahv, Johnson, Chris does apps, Isman Usoh and 17 more
Reacted by Anahi LibreSinn, Joel Day, Miloš Kolčák, interphx, Dominic Bauer, veeKINGPIN, Jihad D. Waspada, cjahv, Alexander Trauzzi, Gilly Barr and 11 more
Reacted by Gentry Riggen, BrunoLM, cjahv, Fabrizio Rizzonelli, Darin Hoover, Brian Frichette and Paul Marlow
Reacted by Darin Hoover, pupipipu, Lakshya Agrawal and Sinuhé Coronel
I don't think there much point to yolo-typing this, cause the workarounds listed here and in #8787, specifically the one about using the hints to the function call, aren't that bad (especially with IDE templates for component classes) and having an any-typed component is sad. :( Any-typing connect just to use it as a decorator instead of a function call is really putting the cart before the horse.
@npirotte Agree. You're absolutely right, using HOCs as decorators violates decorators spec. It's not the base class anymore but completely different one.
I'm having the same exact issues with custom decorators and looking at the state of their support in TS (they're still behind the flag and AFAICS there're no plans to enable them by default) I'm about to drop support for them. Moreover decorators are still in w3c draft.
The best way to wrap a component to a new one is to use a higher order function for it instead of trying to decorate existing class.
If an object is passed, each function inside it is assumed to be a Redux action creator. An object with the same function names, but with every action creator wrapped into a dispatch call so they may be invoked directly, will be merged into the component’s props.
import {connect} from 'path-to-my-connect/connect'
interface IOwnProps {
... props exposed for the real parent component
}
interface IStateProps {
... props from mapStateToProps
}
interface IDispatchProps {
... props from mapDispatchToProps
}
interface IProps extends IStateProps, IDispatchProps, IOwnProps {}
@connect<IStateProps, IDispatchProps, IOwnProps>(
(state: IAppState) => {
return {
foo: getFoo(state), // getFoo is a selector using 'reselect'
}
},
{setFoo, increment, decrement, ... your action creators},
)
class MyComponent extends React.PureComponent<IProps> {
// your component implementation
}
export default (MyComponent as any) as React.ComponentType<IOwnProps>
Direct casting MyComponent as React.ComponentType<IOwnProps> will fail, so I typed it as any first. I know it's a hack but works well for the parent and for the component itself too.
This is the most viable, yet still restrictive solution I have been able to come up with.
@ctretyak nope, you'll eventually have to create a declaration file yourself and modify the decorator. Seems like the React Eco and TS aren't the best friends, hence why I've moved on from it.
Reacted by Sentient Drone and Mo Doaie
Reacted by Kirill Agalakov, John Boehr and Orest Prystayko
this kind of import allows IDE show props and hide ts error. a bit ugly, but decorators looks better then simple connect. especially if you configure to add some selector automatically such as translates or navigation
Any official solutions supplied???
I think there are many developers prefer to use @connect rather than connect(mapStateToProps,mapDispatchToProps)(components)
Hi thread, we're moving DefinitelyTyped to use GitHub Discussions for conversations the @types modules in DefinitelyTyped.
To help with the transition, we're closing all issues which haven't had activity in the last 6 months, which includes this issue. If you think closing this issue is a mistake, please pop into the TypeScript Community Discord and mention the issue in the definitely-typed channel.
Activity
[-]react-redux's `connect` cannot be used as a decorator: "type is not assignable to type 'void'"[/-][+]react-redux's `connect` cannot be used as a decorator: type "is not assignable to type 'void'"[/+]ProTip commentedon Feb 23, 2017
I was having similar issues the other day and dropped it for the connect func. The types looked off and using old react types. I may try to fix this and submit a PR?
seansfkelley commentedon Feb 23, 2017
Of course! A lot has changed since these types were originally written, though I am still skeptical that without mutating-decorator support something useful is possible. But I've worked around other inadequacies in the type system before, so give it a shot.
Perhaps mapped types could get you part of the way there, so at least you have some useful type information in the output?
jwulf commentedon Mar 5, 2017
YOLO
seansfkelley commentedon Apr 16, 2017
I don't think there much point to yolo-typing this, cause the workarounds listed here and in #8787, specifically the one about using the hints to the function call, aren't that bad (especially with IDE templates for component classes) and having an any-typed component is sad. :( Any-typing connect just to use it as a decorator instead of a function call is really putting the cart before the horse.
asterikx commentedon Apr 27, 2017
To use
@connectdirectly (so without introducing custom decorators) I use the following workaround:But I totally agree with @seansfkelley that any-typing is really not what we want to have...
npirotte commentedon May 4, 2017
Despite decorator syntax is cool, I still think using HOC like connect in a standard way is a better practice.
So I would like to say please, don't provide a definition that allows dev to use it the wrong way :)
raveclassic commentedon Jun 28, 2017
@npirotte Agree. You're absolutely right, using HOCs as decorators violates decorators spec. It's not the base class anymore but completely different one.
I'm having the same exact issues with custom decorators and looking at the state of their support in TS (they're still behind the flag and AFAICS there're no plans to enable them by default) I'm about to drop support for them. Moreover decorators are still in w3c draft.
The best way to wrap a component to a new one is to use a higher order function for it instead of trying to decorate existing class.
TriStarGod commentedon Jul 8, 2017
I have the same error if I import it. However, the following works for me:
seansfkelley commentedon Jul 8, 2017
@TriStarGod that depends on how you've typed
require. It seems likely you're ending up withconnecttyped asanyin that case.offbeatful commentedon Jul 23, 2017
Another solution/workaround.
Since I already have my own App State I need some very short function in the form of:
And here is that wrapped connect method:
zheeeng commentedon Aug 22, 2017
Thx for your work. Subscribing and waiting for progress on this issue.
comerc commentedon Sep 1, 2017
@offbeatful please give type declaration of other variation of mapDispatchToProps
pravdomil commentedon Oct 15, 2017
another workaround based on @offbeatful comment
myConnect.ts
offbeatful commentedon Nov 26, 2017
Updated based on @pravdomil snippet and latest types (5.0.13)
5 remaining items
andrew-buckley commentedon Apr 8, 2018
+1 on this issue
jake-daniels commentedon May 15, 2018
I updated snippet from @offbeatful and I'm successfully using it now.
connect.ts (
IAppStateis the interface of redux state)Then my connected component looks like this:
Direct casting
MyComponent as React.ComponentType<IOwnProps>will fail, so I typed it asanyfirst. I know it's a hack but works well for the parent and for the component itself too.This is the most viable, yet still restrictive solution I have been able to come up with.
ctretyak commentedon Aug 31, 2018
any news?
marcus-sa commentedon Sep 10, 2018
@ctretyak nope, you'll eventually have to create a declaration file yourself and modify the decorator. Seems like the React Eco and TS aren't the best friends, hence why I've moved on from it.
ogrinishin commentedon Jan 31, 2019
const DecoratedComponent = require('../DecoratedComponent').default;this kind of import allows IDE show props and hide ts error. a bit ugly, but decorators looks better then simple connect. especially if you configure to add some selector automatically such as translates or navigation
Bastorx commentedon Feb 14, 2019
It's not a react-redux issues. I've the same comportment with the @withRouter (from React-Router) and @graphql
Typescript seems doesn't understand that a decorator could inject props...
matthew-dean commentedon Apr 18, 2019
Ugh, this is still an issue? Just ran into this.
margox commentedon May 13, 2019
I feel sad that something are destorying our brain, but they were designed to make us more comfortable :(
josh-axy commentedon Sep 7, 2019
me too :(
nsmithdev commentedon Sep 7, 2019
This probably does not cover all use cases but has been working good for me.
It also gives me a chance to add my store type (MyAppStore) in one place.
isalox commentedon Dec 5, 2019
do you have any updates?
DalerAkhmetov commentedon Mar 18, 2020
I'd like to use connect as decorator too.
LynnWonder commentedon Jun 20, 2020
Any official solutions supplied???
I think there are many developers prefer to use @connect rather than connect(mapStateToProps,mapDispatchToProps)(components)
orta commentedon Jun 7, 2021
Hi thread, we're moving DefinitelyTyped to use GitHub Discussions for conversations the
@typesmodules in DefinitelyTyped.To help with the transition, we're closing all issues which haven't had activity in the last 6 months, which includes this issue. If you think closing this issue is a mistake, please pop into the TypeScript Community Discord and mention the issue in the
definitely-typedchannel.