I have a library that is using Flow types. It also has a dependency, and part of its interface includes type definitions from the flow-typed
file for that library. I'm using flow-copy-source
to ensure there are .js.flow
files present in the installed package.
The problem I'm having is that when the consumer of this library imports my module, the type imports from the dependency are also imported, but the consumer now has to install its own copy of the flow-typed
definitions for that dependency. Normally that'd be fine, but if that consuming code has a different version of that dependency itself, there isn't a way to avoid conflicting definitions.
To put this concretely, my library is an HTTP service wrapper using [email protected]
and has imports like this:
import type { Axios, AxiosXHRConfig } from 'axios';
AxiosXHRConfig
in version 0.18.x
of the flow-typed
definition takes two type parameters. In the meantime, the consuming application is using an older version of axios
and has a different version of axios library definition for that older version. Since both library definitions have:
declare module "axios" {
// ...
}
...that import type { ... } from 'axios'
in the library doesn't have a way to resolve to the flow-typed/npm/axios_v0.18.x.js
in the library instead of the consuming application's flow-typed/npm/axios_v0.17.x.js
.
Short of duplicating the flow-typed
definitions in the library, how do you make distributable flow-typed packages with global type dependencies that can be safely consumed by other flow projects?
I'm taking this approach as a manual workaround until I hear of a more automatic way to do this:
/src/interface.js
flow file with only the public interface for my libraryflow-copy-source
/src
and transpiled/lib
directory.index.js
andindex.js.flow
that wipe away the typing for the implementation of the interface, like this:index.js:
index.js.flow:
This solves the original problem because the third-party dependency is now effectively encapsulated and doesn't reach outside of the exposed interface.