Flow: Libdef syntax: Export default + named exports

Created on 24 Aug 2016  路  4Comments  路  Source: facebook/flow

Hi!
I have a very delicate problem to express the redux-saga module export interface:

// consumer.js
import createSagaMiddleware from 'redux-saga';
import { takeEvery } from 'redux-saga';

So I know how to express takeEvery, like this:

// flow-typed/redux-saga.js

declare module 'redux-saga' {
  declare type takeEvery: () => any;
}

I also know how I could export createSagaMiddleware:

// flow-typed/redux-saga.js

declare module 'redux-saga' {
  declare module.exports: () => any;
}

But I cannot do this:

// flow-typed/redux-saga.js

declare module 'redux-saga' {
  declare type takeEvery: () => any;
  declare module.exports: () => any;
}

In the last example, flow will only recognize the default export, but not the named exports...

I know there are limitations, since flow will either switch between CJS / ES module mode.
Is there any workaround for this? This is a blocker to express my almost-finished redux-saga libdefs.

bug

Most helpful comment

@samwgoldman Okay nevermind, I looked through the test-folder and found this: https://github.com/facebook/flow/blob/master/tests/declare_export/ES6_DefaultAndNamed.js

To clear things up for other people:

  • If you use declare module.exports: SomeType, flow interprets the module as CommonJS, so it doesn't export all other declare var whatevers
  • If you use declare export default myFunc it will interpret the declared module as an ES module, that means you have to define each named export as declare export var foo: T
  • If you neither use the export nor the declare module.exports keywords, then all declare var entities will just be exported as named exports

I really need to update the official docs for this... it's actually straight-forward as soon as you played around with it.

So it's not a bug, I will close this.

All 4 comments

Hey, thanks for such a clear writeup of the problem! I haven't repro'd this, but from the examples it definitely seems like this should work.

IIRC, a non-libdef module can certainly export types, named exports, and a default export, so a libdef module should be able to as well.

I'm about to get on a plane, but I'll check this out when I land.

@samwgoldman Okay nevermind, I looked through the test-folder and found this: https://github.com/facebook/flow/blob/master/tests/declare_export/ES6_DefaultAndNamed.js

To clear things up for other people:

  • If you use declare module.exports: SomeType, flow interprets the module as CommonJS, so it doesn't export all other declare var whatevers
  • If you use declare export default myFunc it will interpret the declared module as an ES module, that means you have to define each named export as declare export var foo: T
  • If you neither use the export nor the declare module.exports keywords, then all declare var entities will just be exported as named exports

I really need to update the official docs for this... it's actually straight-forward as soon as you played around with it.

So it's not a bug, I will close this.

Thanks, I meet the same problem.

@ryyppy Your explanation here was very helpful. Much clearer than the Creating Library Definitions docs here: https://flow.org/en/docs/libdefs/creation/

Was this page helpful?
0 / 5 - 0 ratings