-
Notifications
You must be signed in to change notification settings - Fork 30.2k
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Enzyme instance() method should be able to carry type of wrapped class #26039
Comments
I like the idea of extra generic parameter but it should all be infered so users don't have to pass all those generic parameters |
Generic type parameters that are generics themselves work just fine in TypeScript. I have not looked into this particular issue but you should be able to make it work. I think you're on the right track here. Please give it another shot and let me know if that didn't work :) |
It's not possible to get the component type from a JSX expression because the return type of all JSX expressions is currently just The third instance type parameter isn't great because the first two are actually on that type. One option is to drop down to one parameter, the component type, and use index types to get props and state. It would be a fairly massive breaking change, but it seems to work pretty well, and could even give you methods off of declare class Test extends React.Component<{ a?: number }> {
method(): void;
}
declare function shallow<C extends React.Component = React.Component>(node: JSX.Element): ShallowWrapper<C>;
interface ShallowWrapper<C extends React.Component> {
props(): C['props'];
state(): C['state'];
instance(): C;
}
const wrapper = shallow<Test>(<Test />);
wrapper.props().a; // ok, number
wrapper.instance().method; // ok, () => void; |
JSX (React.crrateElement really) is breaking the types here. The only way to solve this is to have a runtime function in typescript that accepts the component class and props and will invoke React.createElement in it with shallow wrapped in it. |
I mean something like this: function shallow (componentClass, props) {
return enzyme.shallow(<componentClass {...props} />)
} |
With @Hotell generic syntax you can have a runtime wrapper function that removes the need of casting or providing generic type: import enzyme from 'enzyme';
function shallow<P = {}, C extends React.Component<P>>(ComponentClass: typeof C, props: P) {
return enzyme.shallow<C>(<ComponentClass {...props} />)
} with that, this should work: class MyComponent extends React.Component<{foo: number> {
render() { return null }
someMethod() { }
}
swallow(MyComponent, {foo: 42}).instance().someMethod() |
that is unnecessary boilerplate @mohsen1 all you need to do from now on is in demonstrated in test https://github.com/DefinitelyTyped/DefinitelyTyped/pull/26565/files#diff-2931280905f283a37c4795c53167755cR354 class MyComponentWithMethods extends React.Component<{}, {}> {
someMethod() {
return 'some string';
}
}
test('instance type by providing component type explicitly works', () => {
const wrapper = shallow<MyComponentWithMethods>(<MyComponentWithMethods />);
expect(wrapper.instance().someMethod()).toBe('some string');
}
} |
I mean if you don't want to repeat component type in the generic you can do that runtime function :) |
This works well with e.g.
|
You need to declare the type of |
Can this work for functional components? Like function MyComponentWithMethods(): JSX.Element {
function onButtonClick(): void {
console.log('Button clicked!');
}
return (<button onClick={onButtonClick}>Click me!</button>);
} |
Relevant TypeScript issues:
|
|
This is an issue to track the problem meant to be addressed by #18043
If you know how to fix the issue, make a pull request instead.
@types/xxxx
package and had problems.Definitions by:
inindex.d.ts
) so they can respond.Issue
Calls to
shallow(..).instance()
should have the type of the component they wrap.Example
(thanks to @mohsen1 - took straight from the test PR)
Result:
Workaround: cast the output of
instance
Possible solution: add a third property parameter to
shallow
This would mean that the test above would pass with the following change:
I can try to put together a PR if that seems like a sensible idea.
The text was updated successfully, but these errors were encountered: