material-ui-pickers: [Typescript] TypeError: Utils is not a constructor
Environment
| Tech | Version |
|---|---|
| material-ui-pickers | 2.0.4 |
| material-ui | 1.2.2 |
| React | 16.5.0 |
| Browser | Chrome / Node |
| Peer library | moment -> 2.22.2 |
Steps to reproduce
- Given the following component:
import MomentUtils from "@date-io/moment";
import DatePicker from "material-ui-pickers/DatePicker";
import MuiPickersUtilsProvider from "material-ui-pickers/MuiPickersUtilsProvider";
import * as moment from "moment";
import "moment/locale/es";
import * as React from "react";
moment.locale("es");
export function CustomDatePicker(props) {
const { date, handleDateChange, ...rest } = props;
return (
<MuiPickersUtilsProvider utils={MomentUtils} moment={moment} locale="es">
<DatePicker
value={date}
onChange={handleDateChange}
{...rest}
/>
</MuiPickersUtilsProvider>
);
}
export default CustomDatePicker;
- When mounted in a test using Jest + Enzyme like this:
it("renders without crashing", () => {
let elem = mount(
<CustomDatePicker
date={new Date().toString()}
handleDateChange={e => console.log(e)}
/>
);
});
- I get the following runtime error:
TypeError: Utils is not a constructor. If I useshallowinstead then the test passes, but I get this warning:Warning: Failed prop type: The prop 'utils' is marked as required in 'MuiPickersUtilsProvider', but its value is 'undefined' in MuiPickersUtilsProvider.
In the real world, A.K.A outside of my tests the actual component seems to mount and work without issues, but this messes up not only my unit tests but all my integration tests.
Expected behavior
MuiPickersUtilsProvider shouldn’t complain, my component should mount inside the test, and the test should pass.
Live example
I’m trying to reproduce this here, but MuiPickersUtilsProvider just refuses to render (?) 🤔 https://codesandbox.io/s/20j8zl8zzj
Thanks in advance for your help y’all!
About this issue
- Original URL
- State: closed
- Created 6 years ago
- Reactions: 1
- Comments: 16 (7 by maintainers)
So I played around with a bunch of combinations in tsconfig.json and tsconfig.test.json for
module,esModuleInteropandallowSyntheticDefaultImports.The winning combo for my project was:
tsconfig.json
tsconfig.test.json
I hope that helps anybody facing the same issue. I think the issue can now be closed.
What’s funny is that I cannot replicate what I have on my real-life project. In this project the following happens:
Using
import MomentUtils from "@date-io/moment"works for the actual rendering with React-DOM, but breaks my tests.Using
import * as MomentUtils from "@date-io/moment";makes the tests pass, but breaks the rendering of with React-DOM.In both cases (respectively) the error is that instead of the
MomentUtils(_a) { … }constructor function, the component receives an object that contains the constructor, like so{default: MomentUtils(_a) { … }}. I can make it work in this case by passing it like soutils={MomentUtils.default}, but because the import result is always the other way around on my tests I always break either the tests or the real thing… 🤔 this is driving me nuts hahaha!EDIT — Correction: calling
import MomentUtils from "@date-io/moment"results in MomentUtils being nothing in the test env?