I have a HOC to test, during shallow mount I should to call some class methods:
it('Should not call dispatch', () => {
const dispatch = jest.fn()
const WrappedComponent = someHoc(DummyComponent)
const instance = shallow(
<WrappedComponent
dispatch={dispatch}
/>,
).instance() as WrappedComponent
instance.someMethod()
expect(dispatch).toHaveBeenCalledTimes(0)
})
test works fine but TS piler throws an error
Cannot find name 'WrappedComponent'.
And it is right because WrappedComponent is not a type or class, but if I remove the
as WrappedComponent
line, TS throws an error
Property 'someMethod' does not exist on type 'Component<{}, {}, any>'.
Also, it does not pile if I change that line as
as typeof WrappedComponent
someHoc description:
import ...
interface State {
/*state*/
}
interface Props {
dispatch: Dispatch<Action>
/*props*/
}
export someHoc = <T extends {}>(
ChildComponent: React.ComponentClass<T>,
) => {
class Wrapper extends React.PureComponent<T & Props, State> {
someMethod = () => {
/*do smth*/
}
render() {
return (
<div>
<ChildComponent {...this.props} />
</div>
)
}
}
return Wrapper
}
How can I type the HOC instance? Thanks.
I have a HOC to test, during shallow mount I should to call some class methods:
it('Should not call dispatch', () => {
const dispatch = jest.fn()
const WrappedComponent = someHoc(DummyComponent)
const instance = shallow(
<WrappedComponent
dispatch={dispatch}
/>,
).instance() as WrappedComponent
instance.someMethod()
expect(dispatch).toHaveBeenCalledTimes(0)
})
test works fine but TS piler throws an error
Cannot find name 'WrappedComponent'.
And it is right because WrappedComponent is not a type or class, but if I remove the
as WrappedComponent
line, TS throws an error
Property 'someMethod' does not exist on type 'Component<{}, {}, any>'.
Also, it does not pile if I change that line as
as typeof WrappedComponent
someHoc description:
import ...
interface State {
/*state*/
}
interface Props {
dispatch: Dispatch<Action>
/*props*/
}
export someHoc = <T extends {}>(
ChildComponent: React.ComponentClass<T>,
) => {
class Wrapper extends React.PureComponent<T & Props, State> {
someMethod = () => {
/*do smth*/
}
render() {
return (
<div>
<ChildComponent {...this.props} />
</div>
)
}
}
return Wrapper
}
How can I type the HOC instance? Thanks.
Share Improve this question edited Sep 2, 2023 at 15:24 Alex Borodin asked Oct 16, 2018 at 19:56 Alex BorodinAlex Borodin 2,0341 gold badge15 silver badges30 bronze badges 2-
What's
someHoc
? How is it typed? Also, it does not pile if I change that line as - what is the error? – Estus Flask Commented Oct 16, 2018 at 21:04 - @estus just added some description – Alex Borodin Commented Oct 16, 2018 at 21:13
2 Answers
Reset to default 6It is expected that functions that have variable return value types that can be parametrized are generics. shallow
is a generic:
export function shallow<C extends Component, P = C['props'], S = C['state']>(node: ReactElement<P>, options?: ShallowRendererProps): ShallowWrapper<P, S, C>;
export function shallow<P>(node: ReactElement<P>, options?: ShallowRendererProps): ShallowWrapper<P, any>;
export function shallow<P, S>(node: ReactElement<P>, options?: ShallowRendererProps): ShallowWrapper<P, S>;
It likely should be used as:
const instance = shallow<typeof WrappedComponent>(
<WrappedComponent
dispatch={dispatch}
/>,
).instance();
There currently seem to be problems in Enzyme typings with using generic parameters to infer ponent type in ShallowWrapper
.
A workaround that secures type safety down the test is to assert the type:
const instance = shallow(
<WrappedComponent
dispatch={dispatch}
/>,
)
.instance() as any as InstanceType<typeof WrappedComponent>;
This is not about HOC
, but in case anyone finds this after Googling for hours, try updating @types/react
to the latest version (I went from 18.0.14
to 18.2.38
).
Which allowed me to use (unmodified)
const about = shallow(<About />);
given
export default function About() {
const foo = true;
return (
<div>Blabla</div>
)
}
with no problems.