Reputation:
I'm trying to write tests for a React Typescript component. App.tsx:
import * as React from 'react';
import { Button } from 'react-bootstrap';
interface Igift {
id: number;
}
interface IAppState {
gifts: Igift[];
}
class App extends React.Component<{}, IAppState> {
public state = {
gifts: []
};
public addGift = () => {
const { gifts } = this.state;
const ids = this.state.gifts.map(ourGift => ourGift.id);
const maxId = ids.length > 0 ? Math.max(...ids) : 0;
gifts.push({ id: maxId + 1 });
this.setState({ gifts });
};
public render() {
return (
<div>
<h2>Gift Giver</h2>
<Button className="btn-add" onClick={this.addGift}>
Add Gift
</Button>
</div>
);
}
}
export default App;
and a test for that component. App.test.tsx:
import { shallow } from 'enzyme';
import * as React from 'react';
import App from './App';
const app = shallow(<App />);
describe('App', () => {
it('renders correctly', () => {
expect(app).toMatchSnapshot();
});
it('initializes the `state` with an empty list of gifts', () => {
expect(app.state().gifts).toEqual([]);
});
it('adds a new gift to `state` when clicking the `add gift` button', () => {
app.find('.btn-add').simulate('click');
expect(app.state().gifts).toEqual([{ id: 1 }]);
});
});
I'm getting a following error:
(14,24): Property 'gifts' does not exist on type 'Readonly<{}>'.
In App.test.tsx I cannot seem to find any details regarding that. The app is bootstrapped with create-react-app with ts version of the scripts. The tests pass but when I try starting the app, it throws that error. What need to be done?
Upvotes: 3
Views: 5780
Reputation: 15106
Because <App/>
has the generic type JSX.Element
, it does not contain enough information to infer the state type in the result of shallow
(the same holds for the props & component types). You can fix it by exporting IAppState
from App.tsx
and parameterizing shallow
with the component, props, & state types:
import App, {IAppState} from './App';
..
const app = shallow<App, {}, IAppState>(<App />); // {} is props type
..
This should also correctly type app.instance()
and app.setProps()
. Alternatively, you could choose to just test in plain JavaScript, as I'm not sure doing this in TypeScript is worth the extra effort.
Upvotes: 3