Reputation: 2644
I am writing a library that will be consumed by 3rd party. I chose flowtype as a typing system (for specific reasons due to my organization). The library exposes annotated React component.
The library is annotated using flowtype. I also want to be able to use it in other code with flowtype. I created index.flow.js
in the library and put following in it:
// @flow
import type MyComponent from './components/my-component'
export default MyComponent
// some other types follow
...
When I try to use the library in different codebase, the types "do not work". For example if I pass invalid prop to the component, the type system does not throw any errors. My codebase is typed using flowtype as well.
Should I declare my React in component in library's index.flow.js
file? That seems awkward because now I have to maintain the types at two places (the component itself and the flow file).
I was thought that the flow works by default. Since my React component is typed and the library is exposing index.flow.js
it would recognize that the component has specific types for props, state etc. but it does not.
Upvotes: 1
Views: 743
Reputation: 2644
So after some researching I've come to conclusion that there are two approaches:
Make sure to create definition file as same as your distribution JS filename. This means if you have library lib-a
with bundled file lib-a.js
, name the definition file lib-a.js.flow
. Follow Flow documention on creating library definitions on how to correctly define your module.
With this approach you need to declare the whole module inside it. It means if you have a class MyComponent
, you need to define it here again.
I didn't like this approach because everything needs to be in one place. In you source code you then need to import the types from the definition file so you don't end up duplicating type definitons. This is not so great, for example with React you end up importing Props
type from the main definition file which makes it less readable instead of having the types in-line. This approach can be good for small libraries I guess.
Using this approach you basically copy all your non-transpiled / un-bundled source code with distribution file. These files will end with *.flow
extension which means that Flow will pick these up only for type analysis. Read this article on how to get it working.
In short you basically:
flow-copy-source
as dev dependencyAdd this to package.json
:
"build:flow": "flow-copy-source -v -i '**/__tests__/**' src lib"
Where src
is the folder of your source code and lib
is the folder of your distribution file(s) which are eventually consumed (and probably in npm
repository).
One could argue that this approach is "hacky" and pollutes the distribution package. I agree, it's not very clean solution but probably the best I've found so far. Please read the provided article and the comments to get more insight on what other things you could do.
I have come across this Github thread where this exact problem is being discussed. It seems like gen-flow-files
is about to be removed and my used approach is the way forward for now.
Upvotes: 1