Skip to content

TypeScript to Flow Types — Numio

Converts TypeScript type declarations into Flow types with flowgen. readonly becomes the + variance marker, exported functions and classes become "declare export", and enums become exact read-only objects.

You publish a TypeScript library and also want to ship Flow definitions for consumers who use Flow.

TypeScript

Flow

When to use it

  • You publish a TypeScript library and also want to ship Flow definitions for consumers who use Flow.
  • A Flow codebase depends on a package that only has .d.ts types and you need a libdef to start from.

How to use

  1. Paste TypeScript declarations (interfaces, types, declare statements, enums) or a module with implementation code into the TypeScript panel.
  2. The code is posted to /api/typescript-to-flow. Code with function bodies or initializers is first reduced to a .d.ts by the TypeScript compiler; flowgen then converts and beautifies it.
  3. Copy the Flow output, put it in your flow-typed folder or a .js.flow file, and run flow to check it.

TypeScript

export type Theme = "light" | "dark";

export interface ButtonProps {
  label: string;
  theme?: Theme;
  readonly disabled: boolean;
  onClick(event: MouseEvent): void;
}

export declare function render(props: ButtonProps): string;
export enum Size { Small, Large }

Flow

export type Theme = "light" | "dark";
export interface ButtonProps {
  label: string;
  theme?: Theme;
  +disabled: boolean;
  onClick(event: MouseEvent): void;
}
declare export function render(props: ButtonProps): string;

declare export var Size: {|
  +Small: 0, // 0
  +Large: 1, // 1
|};

Details and limitations

The page sends your input to a server route (/api/typescript-to-flow) for conversion; it is not processed only in the browser. Next.js API routes accept request bodies up to 1 MB by default.

Implementation code is compiled to declarations first, so only its typed API remains: bodies disappear, inferred return types are filled in, and non-exported values that no export uses are dropped.

Object type aliases become inexact Flow objects ending in "..."; interfaces stay interfaces.

Numeric enums become a declared exact object of read-only literal values, for example +Small: 0.

FAQ

How are readonly properties converted?

readonly disabled: boolean becomes +disabled: boolean, Flow's covariant (read-only) property marker.

Can I paste a full .ts file with implementations?

Yes. The server emits declarations first, so an untyped arrow function gets its inferred type, for example declare export var greet: (u: User) => string. Syntax errors are reported instead of converted.

Are TypeScript enums supported?

Yes, as declare export var Name: {| +Member: value |}. Flow enums are not generated.

Specifications and references