Research
Security News
Malicious npm Package Targets Solana Developers and Hijacks Funds
A malicious npm package targets Solana developers, rerouting funds in 2% of transactions to a hardcoded address.
babel-plugin-reflow
Advanced tools
Babel plugin to transpile Flow types to TypeScript with CLI wrapper.
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.
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
yarn add --dev babel-plugin-reflow
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/
TODO
TODO
Some Flow types are not equivalently expressible in TypeScript. See the list of unsupported 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 Reflow CLI will output a warning with the source code location, whenever one of the following cases are encountered:
TypeScript intentionally doesn't support return types for constructor functions. These will be removed by Reflow.
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
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 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 types are not supported in TypeScript and are transformed to an ordinary type alias.
opaque type T = number; // Flow
type T = number; // TypeScript
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.
This Babel plugin enables a few other Babel plugins to support various kinds of syntax:
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)
FAQs
Babel plugin to transpile Flow code to TypeScript
The npm package babel-plugin-reflow receives a total of 119 weekly downloads. As such, babel-plugin-reflow popularity was classified as not popular.
We found that babel-plugin-reflow demonstrated a not healthy version release cadence and project activity because the last version was released a year ago. It has 1 open source maintainer collaborating on the project.
Did you know?
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.
Research
Security News
A malicious npm package targets Solana developers, rerouting funds in 2% of transactions to a hardcoded address.
Security News
Research
Socket researchers have discovered malicious npm packages targeting crypto developers, stealing credentials and wallet data using spyware delivered through typosquats of popular cryptographic libraries.
Security News
Socket's package search now displays weekly downloads for npm packages, helping developers quickly assess popularity and make more informed decisions.