Search code examples
reactjsreact-nativereduxflowtype

How to organize flowtype in react + redux project


just wanted to gather some opinion of on how to organizing flowtype in react + redux project. Here some example project structure:

actions
    -> UserAction.js ---> has some flowtype definition related to this action
    -> PostAction.js ---> has some flowtype definition related to this action
    ...
reducers
    -> UserReducer.js ---> has some flowtype definition related to this reducer
    -> PostReducer.js ---> has some flowtype definition related to this reducer
    ...
models
    -> User.js ---> has some flowtype definition related to this model
    -> Post.js ---> has some flowtype definition related to this model
    ...
components
containers

However, i see some open source projects, such as f8 is using a single file to define all the types, for eg:

actions
    -> UserAction.js
    -> PostAction.js
    -> types.js --> all types related to actions
    ...
reducers
    -> UserReducer.js
    -> PostReducer.js
    -> types.js --> all types related to reducers
    ...
models
    -> User.js --->
    -> Post.js --->
    -> types.js --> all types related to models
    ...
components
containers

Thus, i just want to get opinion on how to organize flowtype in a more sustainable and readable way. Thank you


Solution

  • First of, I'd like to be clear on terminology; flow-typed and flow types are two different, but related, concepts.

    In this case, we're talking about flow types in general, as opposed to flow-typed, which is a type repository similar in concept to TypeScript's Definitely Typed repository.

    Flow Types are exported types to be used in a library, and as such have many different ways one could organize them. This is partially driven by the fact that types need to be imported before they are used, so at the top of the file. Because of this, it makes sense to organize them outside of the file in some cases. This is a similar case to how constants are treated.

    The first example elects to keep each type in their respective class, and this works for most cases but can promote circular dependencies in larger projects. This option has less source files to manage, which is a positive in smaller projects.

    The second example elects to export types per construct; ex: All actions export their types together. This reduces the chance for circular dependencies, as well as making it clear where to import the types from. For larger projects, I would suggest this option.

    instead of :

    import type { FooType } from './foo';
    import type { BarType } from './bar';
    

    we can just :

    import type { FooType, BarType } from './types';