Flow: Is there an interface generator?

Created on 11 Aug 2015  路  11Comments  路  Source: facebook/flow

I would like to write some libraries with flow in mind. This libraries should be published so that other users out there can use it. The libraries should be useable for users that are using flow as well for users that are not using flow.

My first thought was that I write my code with Babel and add flow type annotations. My build system (I am using Gulp) transforms my code to ES5 compatible code, strips out flow type annotations and put it in a lib directory. This lib directory will be published to npm. Why / how I do this is explained here. So far so good. Everyone can now use my library and is not forced to use flow, Babel or something else.

But what if someone want to use my library with type annotations? He has to add an interface file. But it would be much more comfortable when the library already would provide those interface files. So my second thought was to add these interface files by myself to my library and add it to my lib directory for exporting. But this forces me to write this interface files by hand. So I have to write the types to my js files and once again to the interface files.

Is there a way to automatically generate the interface files for me? Or am I completely on the wrong way for this whole thing?

feature request

Most helpful comment

One thing I would recommend differently from what flow-static-land does is to put that stuff in the "prepare" step (instead of "build") under package.json's scripts, so it'll be automatically run when npm install is run from the project's directory, and right before npm publish is run. (Assuming npm >= v4. Previously it was "prepublish" that did this.)

All 11 comments

But it would be much more comfortable when the library already would provide those interface files. So my second thought was to add these interface files by myself to my library and add it to my lib directory for exporting.

Here's an issue I opened about this part: https://github.com/facebook/flow/issues/593 . I think it's pretty much a prerequisite step for this. I do agree with this issue that auto-generating interface files for a module would be useful.

Check out http://flowtype.org/blog/2015/02/20/Flow-Comments.html and the related babel plugin, https://github.com/babel-plugins/babel-plugin-flow-comments

Instead of stripping out the annotations, convert them to comments. Flow will still be able to read them, but it'll be valid ES5.

An interface generator would be useful for other things, though, so I'm going to leave this open for now.

@mroch I recommended the same approach to someone else, and they brought up a very good point which prevents the transpile-to-comments approach from working for most people. :disappointed:

The only way to really make transpile-to-comments work is if you only use that feature, and maybe a handful of other features where Flow understands the code on the other side. I don't have any solutions beyond that, but hopefully this will save someone else some time going down that road.

So correct me if I am wrong: at the moment there is no solution for my problem? I can't export flow type annotations for my node library that is written in Babel?

@ScreenDriver Yeah, unfortunately the workflow for this isn't really fleshed out. You can distribute your source code with type annotations separately in the mean time, although I realize this is far from ideal.

:sob:

@ScreenDriver what about putting your interface file in the root of your package? If the user wants to use it it can just include it in the config, or even import types from it. I'm not yet familiar with using interface files, I'm using the approach of name_mapper as described in the comment from @samwgoldman, in combination with having a types file in the root of the package so that I can require it with babel with: import {TypeA, TypeB} from 'library/flow/types';

That said, it'd be great to have a way to compile the types in a library into an interface file in order to publish just that in the npm package

The problem with putting the interface file in the root of my package is that I have to write it manually. I have to write every type declaration twice: in the source code files and in the interface file. If I forget one of those files the other one is useless. This approach would be very cumbersome.

For people stumbling across this issue, I think the solution was to add .flow definition files (see https://github.com/facebook/flow/issues/593#issuecomment-161157179).

In particular, https://github.com/AgentME/flow-copy-source might be useful; eg. GCanti's flow-static-land, as part of the build step, takes Flow originals and:
1) Puts compiled ES5 in lib/, and
2) Makes the original Flow definitions available alongside them as .flow definitions, for consumption by code using the library.

One thing I would recommend differently from what flow-static-land does is to put that stuff in the "prepare" step (instead of "build") under package.json's scripts, so it'll be automatically run when npm install is run from the project's directory, and right before npm publish is run. (Assuming npm >= v4. Previously it was "prepublish" that did this.)

flow-gen-files replacement is coming soon

Was this page helpful?
0 / 5 - 0 ratings