Note: this post was originally published on my Medium profile
When refactoring a Higher-Order Component (HOC) in a TypeScript project at work, the...
For further actions, you may consider blocking this person and/or reporting abuse
Nice post, just what I was looking for!
I think you can shorten
React.ComponentClass<TOriginalProps & InjectedProps>
| React.StatelessComponent<TOriginalProps & InjectedProps>
into
React.ComponentType<TOriginalProps & InjectedProps>
at least in newer react typings.
Thank you for the suggestion, I'll look into it :)
Hello Dan, thank you very much for this detailed introduction to typing HOCs. I'm just migrating from flow to typescript (one reason are HOCs AND performance).
I have one question. In case
DemoComponent
would not require thetext
prop, the interface would look like this:When I now use
Demo
orDemoWithDebug
in my app (as in<Demo/>
or<DemoWithDebug/>
), everything works fine and Typescript does not complain. But since I have an empty interface, I thought I could remove it.But then the compiler starts complaining that the InjectedProp
props
is/are missing.I assume this is because the compiler does not understand that the injected props are coming from my HOC and that
<Demo/>
or<DemoWithDebug/>
should provide it.That still makes sense somehow. But we do I need an extra interface here? The following does not work. Is
{}
different from explicitly defining an interface?This seems to be wrong. Or is there a short form ?
const DemoComponent = (props: {} & InjectedProps): JSX.Element
Hi, if I understand you correctly, you really should be able to remove the
DemoProps
interface altogether and write:const DemoComponent = (props: InjectedProps): JSX.Element
What exactly does the TypeScript. compiler say?
When I try this, the compiler complains that
<DemoComponent/>
(when it's being used) does not provideInjectedProps
. If I keep the empty interface, the compiler does not complain. I do remember having read something similar related to flow. I mean that you have to explicitly set an empty object in addition to the injected props, but I may be wrong.Even though, I do not understand why there is is a difference between declaring the
Props
explicitly via an interface, which works, and simply settingconst DemoComponent = (props: {} & InjectedProps): JSX.Element
which does not work.here is a link to a little sandbox: codesandbox.io/s/9zvrln93z4
if you replace
Props
with{}
inhoc/HocA.tsx
, it'll tell you the following in index.tsx:message
in the case of the sandbox is part of theInjectedProps
defined inhoc/withHocA.tsx
I tried replicating what you describe, but for me it works without problems even without the
Props
added.codesandbox.io/s/1kkkyyjpl
Hey there Dan,
MadProps
for this article.Going forward with this example, how would you use ReactDOM.render with this component?
Say we continue with this:
Then our calling code would do
And we'd have to pass in something into
stuff
, which is of type<TOriginalProps & InjectedProps>
Is that right?So what's the point of having injected props calculated within the HOC definition? Am I missing something? If I want to render the
Demo
HOC, don't I have to give it all the props it needs? I think I'm missing the point...Hi, thanks for the
MadProps
:)<Demo>
has props of typeTOriginalProps & ExternalProps
(noInjectedProps
).<DemoComponent>
has props of typeTOriginalProps & InjectedProps
.Look at the diagram at the start of the article, it should make the prop types flow clearer :)
If you need to interact with props or states from here, the only way to do it is to specify options as functions, that take the props or states as arguments.
Trying to get this working, but having issues with it. Any suggestions? Great article btw.
What kind of issues are you having?
The idea is that you pass something like this to the config:
Have you thought of using
compose
fromrecompose
for componsing HOCs ?I could not get my typings working using
compose
.Unfortunately, I haven't. Reading the docs, they say it works similarly to
lodash
'sflow
, which I have used and also had problems with the types (they were too liberal, allowing for errors).Excellent post, Dan - tons of powerful stuff demonstrated, and a great example of an elegant HOC. Thanks for sharing!
Thank you so much for your kind words, it means a lot :)
Thank you, Dan! That article helps me a lot!
Thank you, I'm glad it helped :)
Excellent article, I've been looking for this for days. Thanks a ton!!
Thank you for your kind words, I'm glad it helped you :)