Below is a simple component for showing error messages:
// @flow
import styles from 'styles/components/Error';
import React from 'react';
import CSSModules from 'react-css-modules';
type Props = {
message: string
}
const Error = ({ message }: Props) => {
return (
<div styleName="error">
{message}
</div>
);
};
export default CSSModules(Error, styles);
Note that it requires message
property. Now if I use this component somewhere:
<Error />;
Flowtype should warn me that Error
is missing required property message
but it does not. If I do not wrap my Error
component with react-css-modules, Flowtype does work as expected.
I'm thinking that I need to declare a type for Flowtype for it to understand wrapped components but my Google-fu did not yield any results.
What I did found:
This has been recently discussed on GitHub. Here's the relevant issue: https://github.com/facebook/flow/issues/2536
In short, the problem is that Flow does not have any type information for the CSSModules
function, so the return type is inferred as any
.
In other words:
export default Error; // the type of this export is (_: P) => ?React$element<any>
export default CSSModules(Error, styles); // the type of this export is any
Long story short, you can provide your own type definition. I'll paste here the one suggested by @gcanti in the original issue:
declare module 'react-css-modules' {
declare type CssOptions = {
allowMultiple?: boolean,
errorWhenNotFound?: boolean,
};
declare type FunctionComponent<P> = (props: P) => ?React$Element<any>;
declare type ClassComponent<D, P, S> = Class<React$Component<D, P, S>>;
declare function exports<D, P, S, C: ClassComponent<D, P, S> | FunctionComponent<P>>(reactClass: C, styles: Object, cssOptions?: CssOptions): C;
}
Save the above in decls/react-css-modules.js
or something similar and then configure your .flowconfig
like:
[libs]
decls/.js
This will preserve the type information when wrapping a component into CSSModules
and allow flow to catch the intended errors.