- Notifications
You must be signed in to change notification settings - Fork3
Convert a Flow typed codebase to TypeScript (Babel plugin)
License
grubersjoe/reflow
Folders and files
Name | Name | Last commit message | Last commit date | |
---|---|---|---|---|
Repository files navigation
Babel plugin to transpileFlow types toTypeScript with CLI wrapper.
Reflow enables you to migrate a whole Flow based project to TypeScript bytranspiling the Flow type annotations to equivalent TypeScript code. While thisreduces the effort to move a large code base to TypeScript drastically, it isstill very likely that you will face new type errors after the migration due tothe differences between Flow and TypeScript. See thisrepository for an excellentoverview of the differences and similarities of Flow and Typescript.
Of course, I am aware that other approaches exist to translate Flow toTypeScript. For instance, there isKiikurage/babel-plugin-flow-to-typescriptandKhan/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 notexist yet. Therefore this plugin was developed to solve the given problem of thethesis in practice.
Advantages of Reflow
- can be used either as standalone Babel plugin or through the included CLI totranspile whole code bases
- well tested with high code coverage
- proven to work with real React based projects (two code bases with 27 and 41kLOC respectively were successfully migrated)
- generates well formatted output based on Prettier with focus on placingcomments at the correct position (Babel fails to do so)
yarn add --dev babel-plugin-reflow
This package includes a small CLI wrapper for the Babel plugin to recursivelytranspile whole directories or single files. Install the package as projectdependency and runnpx reflow
afterwards. Alternatively you might want toinstall Reflow globally so you can simply typereflow
:
yarn global add babel-plugin-reflow
Usage is as follows:
$ npx reflow --helpUsage: reflow [OPTION]...<FILES OR DIRECTORIES ...>REFLOW - Flow to TypeScript converterOptions: -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 patternfor 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 wrappedfunctioncalls to avoid TypeScript errors (default: false) -h, --help Output ussage informationExamples: $ reflow --replace src/ $ reflow -d -i'**/__tests__/**/*.{js,jsx}' src/ $ reflow -exclude-patterns'**/__tests__/**/*','fixtures/*.js' src/
TODO
TODO
Some Flow types are not equivalently expressible in TypeScript. See the list ofunsupported Flow features below.
Type | Flow | TypeScript |
---|---|---|
Any type | any | any |
Array type | Array<number> | Array<number> |
Boolean literal type | true | true |
Boolean type | boolean | boolean |
Empty type | empty | never |
Exact object type | {| p: number |} | { p: number } |
Function type | (string, {}) => number | (p1: string, p2: {}) => number |
Generic type annotation | let v: <FlowType> | let v: <TSType> |
Generics | type Generic<T: Super> = T | type Generic<T extends Super> = T |
Interface type | interface I { +p: number } | interface I { readonly p: number } |
Intersection type | type Intersection = T1 & T2 | type Intersection = T1 & T2 |
Mixed type | mixed | unknown |
Null literal type | null | null |
Nullable type (Maybe) | ?number | number | null | undefined |
Number literal type | 42 | 42 |
Number type | number | number |
Object type | { [string]: number } | { [key: string]: number } |
Opaque type | opaque type Opaque = number | type Opaque = number |
String literal type | 'literal' | 'literal' |
String type | string | string |
This type | this | this |
Tuple type | [Date, number] | [Date, number] |
Type alias | type Type = <FlowType> | type Type = <TSType> |
Type casting | (t: T) | (t as T) |
Type exports / imports | import type T from './types' | import T from './types |
Typeof type | typeof undefined | undefined |
Union type | number | null | number | null |
Void type | void | void |
Utility Type | Flow | TypeScript |
---|---|---|
Call | $Call<F, T...> | ReturnType<F> |
Class | Class<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> |
$ObjMap<T, F> | any | |
$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> |
$TupleMap<T, F> | any | |
Values | $Values<T> | T[keyof T] |
deprecated | any | |
deprecated | any |
*
Declaration | Flow | TypeScript |
---|---|---|
Class | declare class C {} | declare class C {} |
Export | declare export default () => string | const _default: () => string; export default _default; |
Function | declare function f(number): any | declare function f(p: number): any |
Interface | declare interface I {} | declare interface I {} |
Module | declare module 'esmodule' {} | declare module 'esmodule' {} |
Type alias | declare type T = number | declare type T = number |
Variable | declare var v: any | declare var v: any |
Unsupported: CommonJS export declarations.
Some Flow features are not equivalently expressible in TypeScript. The ReflowCLI will output a warning with the source code location, whenever one of thefollowing cases are encountered:
TypeScript intentionally doesn't support return types for constructorfunctions. These will be removed by Reflow.
Flow'sexistential typehas been deprecated and should be avoided. Still Reflow supports it and willtransform it to
any
.Function types with unnamed parameters
In contrast to TypeScript, parameter names can be omitted in Flow. ThereforeReflow inserts parameter names automatically (
p
for a single parameter andp{i}
for multiple ones).type FunctionType = ({}, Date) => string; // Flowtype FunctionType = (p1: {}, p2: Date) => string; // TypeScript
Flow allows any type for keys in index signatures, but Typescript only accepts
string
ornumber
. Reflow will add index signatures both forstring
andnumber
if a different type is specified in Flow.// Flowdeclare type KeyType;interface I = { [key: KeyType]: number}// TypeScriptinterface I = { [key: number]: number; [key: string]: number;}
Object types can be spread into other object types in Flow. Unfortunately thissyntax is not supported in TypeScript at the moment. Therefore, theseproperties will be ommited in output. Please fix affected object typesmanually.
// Flowtype ObjectWithSpread = { prop: mixed; ...ObjectType;};// TypeScripttype ObjectWithSpread = { prop: unknown;};
Opaque types are not supported in TypeScript and are transformed to anordinary type alias.
opaque type T = number; // Flowtype T = number; // TypeScript
Flow's contravariance sigil
-
is not expressible in Typescript and will beomitted. However, TypeScript does support covariance for certain types (+
becomesreadonly
).// Flowinterface I { +covariant: any; -contravariant: any;}// TypeScriptinterface I { readonly covariant: any; contravariant: any;}
$Call<F, T...>
The
$Call<F, T...>
utility type is transformed to TypeScript'sReturnType<F>
. Since this type only accepts the function type and not thefunction argument types, it is impossible to infer the return type ofpolymorphic functions. TypeScript will assume anunknown
type then.
This Babel plugin enables a few other Babel plugins to support various kinds ofsyntax:
Clone this repository and install the project dependencies:
yarn install
There are various npm scripts for different tasks:
yarn build # Create a production buildyarn dev # Build in development mode and watch for changesyarn format # Format the code with Prettieryarn lint # Run ESLintyarn test # Run fixture testsyarn test:coverage # Run the tests with coverage reportyarn tsc # Check the types (via TypeScript)
About
Convert a Flow typed codebase to TypeScript (Babel plugin)
Topics
Resources
License
Uh oh!
There was an error while loading.Please reload this page.
Stars
Watchers
Forks
Uh oh!
There was an error while loading.Please reload this page.
Contributors3
Uh oh!
There was an error while loading.Please reload this page.