Huge News!Announcing our $40M Series B led by Abstract Ventures.Learn More
Socket
Sign inDemoInstall
Socket

babel-plugin-reflow

Package Overview
Dependencies
Maintainers
1
Versions
23
Alerts
File Explorer

Advanced tools

Socket logo

Install Socket

Detect and block malicious and high-risk dependencies

Install

babel-plugin-reflow

Babel plugin to transpile Flow code to TypeScript

  • 0.5.7
  • latest
  • Source
  • npm
  • Socket score

Version published
Weekly downloads
148
decreased by-13.45%
Maintainers
1
Weekly downloads
 
Created
Source

Reflow

Babel plugin to transpile Flow types to TypeScript with CLI wrapper.

Tests Coverage

I would love to receive feedback whether this plugin worked for you :)!

Reflow enables you to migrate a whole Flow based project to TypeScript by transpiling the Flow type annotations to equivalent TypeScript code. While this reduces the effort to move a large code base to TypeScript drastically, it is still very likely that you will face new type errors after the migration due to the differences between Flow and TypeScript. See this repository for an excellent overview of the differences and similarities of Flow and Typescript.

Why another plugin?

Of course, I am aware that other approaches exist to translate Flow to TypeScript. For instance, there is Kiikurage/babel-plugin-flow-to-typescript and Khan/flow-to-ts. When I started this project in the course of my master thesis in February 2019, the development of the first plugin seemed inactive and the second one did not exist yet. Therefore this plugin was developed to solve the given problem of the thesis in practice.

Advantages of Reflow

  • can be used either as standalone Babel plugin or through the included CLI to transpile whole code bases
  • well tested with high code coverage
  • proven to work with real React based projects (two code bases with 27 and 41 kLOC respectively were successfully migrated)
  • generates well formatted output based on Prettier with focus on placing comments at the correct position (Babel fails to do so)

Installation

yarn add --dev babel-plugin-reflow

Usage

CLI

This package includes a small CLI wrapper for the Babel plugin to recursively transpile whole directories or single files. Install the package as project dependency and run npx reflow afterwards. Alternatively you might want to install Reflow globally so you can simply type reflow:

yarn global add babel-plugin-reflow

Usage is as follows:

$ npx reflow --help

Usage: reflow [OPTION]... <FILES OR DIRECTORIES ...>

REFLOW - Flow to TypeScript converter

Options:
  -v                                Output the version number
  -d, --dry-run                     Perform a trial run printing to stdout instead of writing a file
  -e, --exclude-dirs <pattern ...>  Comma-separated list of directories to recursively exclude (default: ["node_modules"])
  -i, --include-pattern <pattern>   Set the glob pattern for input files (default: "**/*.{js,jsx}")
  -r, --replace                     Process files in-place instead of creating new TS files next to the original JS files
  -D, --replace-decorators          Replace class @decorators with wrapped function calls to avoid TypeScript errors (default: false)
  -h, --help                        Output ussage information

Examples:
  $ reflow --replace src/
  $ reflow -d -i '**/__tests__/**/*.{js,jsx}' src/
  $ reflow -exclude-patterns '**/__tests__/**/*','fixtures/*.js' src/

Programmatically

TODO

As Babel plugin

TODO

Transformations

Base types

Some Flow types are not equivalently expressible in TypeScript. See the list of unsupported Flow features below.

TypeFlowTypeScript
Any typeanyany
Array typeArray<number>Array<number>
Boolean literal typetruetrue
Boolean typebooleanboolean
Empty typeemptynever
Exact object type{| p: number |}{ p: number }
Function type(string, {}) => number(p1: string, p2: {}) => number
Generic type annotationlet v: <FlowType>let v: <TSType>
Genericstype Generic<T: Super> = Ttype Generic<T extends Super> = T
Interface typeinterface I { +p: number }interface I { readonly p: number }
Intersection typetype Intersection = T1 & T2type Intersection = T1 & T2
Mixed typemixedunknown
Null literal typenullnull
Nullable type (Maybe)?numbernumber | null | undefined
Number literal type4242
Number typenumbernumber
Object type{ [string]: number }{ [key: string]: number }
Opaque typeopaque type Opaque = numbertype Opaque = number
String literal type'literal''literal'
String typestringstring
This typethisthis
Tuple type[Date, number][Date, number]
Type aliastype Type = <FlowType>type Type = <TSType>
Type casting(t: T)(t as T)
Type exports / importsimport type T from './types'import T from './types
Typeof typetypeof undefinedundefined
Union typenumber | nullnumber | null
Void typevoidvoid

Utility types

Utility TypeFlowTypeScript
Call$Call<F, T...>ReturnType<F>
ClassClass<T>typeof T
Difference$Diff<A, B>Omit<A, keyof B>
Element type$ElementType<T, K>T[k]
Exact$Exact<T>T
Existential type*any
Keys$Keys<T>keyof T
None maybe type$NonMaybeType<T>NonNullable<T>
Object map$ObjMap<T, F>any
Object map with key$ObjMapi<T, F>any
Property type$PropertyType<T, k>T[k]
ReadOnly$ReadOnly<T>Readonly<T>
Rest$Rest<A, B>Omit<A, Union<keyof B>>
Shape$Shape<T>Partial<T>
Tuple map$TupleMap<T, F>any
Values$Values<T>T[keyof T]
Subtypedeprecatedany
Supertypedeprecatedany

*

Declarations

DeclarationFlowTypeScript
Classdeclare class C {}declare class C {}
Exportdeclare export default () => stringconst _default: () => string; export default _default;
Functiondeclare function f(number): anydeclare function f(p: number): any
Interfacedeclare interface I {}declare interface I {}
Moduledeclare module 'esmodule' {}declare module 'esmodule' {}
Type aliasdeclare type T = numberdeclare type T = number
Variabledeclare var v: anydeclare var v: any

Unsupported: CommonJS export declarations.


Unsupported Flow features / syntax

Some Flow features are not equivalently expressible in TypeScript. The Reflow CLI will output a warning with the source code location, whenever one of the following cases are encountered:

  • Constructor return types

    TypeScript intentionally doesn't support return types for constructor functions. These will be removed by Reflow.

  • Existential Type

    Flow's existential type has been deprecated and should be avoided. Still Reflow supports it and will transform it to any.

  • Function types with unnamed parameters

    In contrast to TypeScript, parameter names can be omitted in Flow. Therefore Reflow inserts parameter names automatically (p for a single parameter and p{i} for multiple ones).

    type FunctionType = ({}, Date) => string;             // Flow
    type FunctionType = (p1: {}, p2: Date) => string;    // TypeScript
    
  • Index signatures

    Flow allows any type for keys in index signatures, but Typescript only accepts string or number. Reflow will add index signatures both for string and number if a different type is specified in Flow.

    // Flow
    declare type KeyType;
    interface I = {
      [key: KeyType]: number
    }
    
    // TypeScript
    interface I = {
      [key: number]: number;
      [key: string]: number;
    }
    
  • Object type spread

    Object types can be spread into other object types in Flow. Unfortunately this syntax is not supported in TypeScript at the moment. Therefore, these properties will be ommited in output. Please fix affected object types manually.

    // Flow
    type ObjectWithSpread = {
      prop: mixed;
      ...ObjectType;
    };
    
    // TypeScript
    type ObjectWithSpread = {
      prop: unknown;
    };
    
  • Opaque Type

    Opaque types are not supported in TypeScript and are transformed to an ordinary type alias.

    opaque type T = number;  // Flow
    type T = number;         // TypeScript
    
  • Variance

    Flow's contravariance sigil - is not expressible in Typescript and will be omitted. However, TypeScript does support covariance for certain types (+ becomes readonly).

    // Flow
    interface I {
      +covariant: any;
      -contravariant: any;
    }
    
    // TypeScript
    interface I {
      readonly covariant: any;
      contravariant: any;
    }
    
  • $Call<F, T...>

    The $Call<F, T...> utility type is transformed to TypeScript's ReturnType<F>. Since this type only accepts the function type and not the function argument types, it is impossible to infer the return type of polymorphic functions. TypeScript will assume an unknown type then.

Supported syntax

This Babel plugin enables a few other Babel plugins to support various kinds of syntax:

Development

Clone this repository and install the project dependencies:

yarn install

There are various npm scripts for different tasks:

yarn build          # Create a production build
yarn dev            # Build in development mode and watch for changes
yarn format         # Format the code with Prettier
yarn lint           # Run ESLint
yarn test           # Run fixture tests
yarn test:coverage  # Run the tests with coverage report
yarn tsc            # Check the types (via TypeScript)

Keywords

FAQs

Package last updated on 30 Aug 2021

Did you know?

Socket

Socket for GitHub automatically highlights issues in each pull request and monitors the health of all your open source dependencies. Discover the contents of your packages and block harmful activity before you install or update your dependencies.

Install

Related posts

SocketSocket SOC 2 Logo

Product

  • Package Alerts
  • Integrations
  • Docs
  • Pricing
  • FAQ
  • Roadmap
  • Changelog

Packages

npm

Stay in touch

Get open source security insights delivered straight into your inbox.


  • Terms
  • Privacy
  • Security

Made with ⚡️ by Socket Inc