Comparison

JSDoc with TypeScript vs Flow

Two ways to type JavaScript in comments: TypeScript's checker reading JSDoc, and Flow's comment types. Where each stands today, and how to move from Flow.

  • Examples checked with TypeScript 5.9

At a glance

Last verified 21 October 2026 with TypeScript 5.9.3 (the examples); Flow per its documentation and releases, not run here.

Compared JSDoc with TypeScriptFlow
Checker tsc, from the typescript packageflow, from the flow-bin package
Types in a .js file JSDoc comments: /** @param {string} name */Flow syntax, or comment types: /*: string */ and /*:: … */
Which files are checked checkJs in jsconfig.json, or // @ts-check per fileFiles with a @flow comment, or all files with all=true in .flowconfig
Type syntax inside the comments TypeScript's: string | null, Readonly<T>, unknownFlow's: ?string, $ReadOnly<T>, mixed, exact objects
Reads the other's types No: Flow comment types are plain comments to tscNo: Flow does not read JSDoc types
Package types .d.ts files, which TypeScript, editors and most tools read.js.flow files and flow-typed definitions
Latest release (21 October 2026) TypeScript 7.0.2 (this site checks with 5.9.3)Flow 0.336.0, 15 October 2026

Two checkers for typed JavaScript

Flow and TypeScript are both checkers for JavaScript, and both can work on plain .js files with the types kept in comments: Flow through its comment syntax, TypeScript through JSDoc. They are separate checkers with separate type systems, and neither reads the other’s annotations.

Where they stand on 21 October 2026, per their own sites: Flow ships frequent releases (0.336.0 on 15 October 2026), and flow.org describes it as a typed dialect of JavaScript used in production at Meta. A 2021 post on Flow’s direction and its open source engagement is now marked historical on the Flow blog. TypeScript’s checker is the one most editors run for JavaScript, and the one packages publish .d.ts files for. We did not run Flow for this page.

The same function, typed both ways

Flow’s comment types put Flow syntax inside comments, so the file runs without a build: /*: Type */ after a name, and /*:: … */ around a whole declaration such as a type alias. To TypeScript those are ordinary comments, so the function below has an untyped parameter, which strict reports, and the wrong call at the bottom passes:

cart.js Error confirmed · TypeScript 5.9.3 · checked 21 October 2026
// @flow
/*:: type LineItem = { sku: string, quantity: number, unitCents: number }; */

export function totalCents(items /*: Array<LineItem> */) /*: number */ {error TS7006: Parameter 'items' implicitly has an 'any' type.
  let sum = 0;
  for (const item of items) sum += item.quantity * item.unitCents;
  return sum;
}

totalCents("not a list");
Flow's comment types are plain comments to tsc.
jsconfig.json for this example
{
  "compilerOptions": {
    "checkJs": true,
    "noEmit": true,
    "strict": true,
    "target": "es2022",
    "module": "nodenext",
    "types": []
  },
  "include": ["**/*.js"]
}

The JSDoc version of the same file, checked by tsc, with the wrong call caught:

cart.js cart.ts Error confirmed · TypeScript 5.9.3 · checked 21 October 2026
/** @typedef {{ sku: string, quantity: number, unitCents: number }} LineItem */

/**
 * @param {LineItem[]} items
 * @returns {number}
 */
export function totalCents(items) {
  let sum = 0;
  for (const item of items) sum += item.quantity * item.unitCents;
  return sum;
}

totalCents("not a list");error TS2345: Argument of type 'string' is not assignable to parameter of type 'LineItem[]'.
type LineItem = { sku: string; quantity: number; unitCents: number };

export function totalCents(items: LineItem[]): number {
  let sum = 0;
  for (const item of items) sum += item.quantity * item.unitCents;
  return sum;
}

totalCents("not a list");error TS2345: Argument of type 'string' is not assignable to parameter of type 'LineItem[]'.
The same function with JSDoc, which tsc reads.
jsconfig.json for this example
{
  "compilerOptions": {
    "checkJs": true,
    "noEmit": true,
    "strict": true,
    "target": "es2022",
    "module": "nodenext",
    "types": []
  },
  "include": ["**/*.js"]
}

Moving from Flow to JSDoc

A file-by-file move works the way any migration to checked JavaScript does: add // @ts-check to a file, rewrite its annotations, remove // @flow. The translations are mostly mechanical:

FlowJSDoc for TypeScript
name /*: string */@param {string} name above the function
/*:: type Item = { … }; */@typedef {{ … }} Item
?string (maybe type)string | null | undefined
mixedunknown
$ReadOnly<T>, $ReadOnlyArray<T>Readonly<T>, readonly T[]
{| a: string |} (exact object){ a: string }: TypeScript’s object literal checks are similar, not identical
import type { T } from "./x"/** @import { T } from "./x.js" */

Two differences need care rather than translation. Flow’s object types are exact by default, while TypeScript checks extra properties only on fresh object literals, so code that relied on exactness elsewhere loses that check. And Flow’s ?T means “may be null or undefined”, which is wider than TypeScript’s optional property a?: T. Run tsc with strict from the first file, so both show up as errors rather than surprises.

For packages, publish .d.ts files when you switch: shipping types from a JavaScript package covers writing them from JSDoc.

Which to choose

Choose JSDoc with TypeScript when…

  • You are starting to type a JavaScript codebase today: editors, packages' .d.ts files and most tooling speak TypeScript.
  • You publish packages: .d.ts files reach the most users.

Choose Flow when…

  • The codebase already uses Flow heavily and works well with it, and the cost of moving is higher than the cost of staying.
  • You rely on Flow-specific checking that you would lose in a move, and have weighed that against the ecosystem around TypeScript.

Questions

Can TypeScript read Flow comment types?

No. To tsc, /*: string */ is an ordinary comment. A parameter typed only that way is untyped to TypeScript, which strict reports as TS7006, as the example on this page shows.

Is Flow still maintained?

Yes. Releases continue (0.336.0 came out on 15 October 2026), and flow.org describes Flow as used in production at Meta. Its tooling and documentation are centered on that use.

Is there an official Flow-to-TypeScript converter?

Meta publishes flow-api-translator, which writes TypeScript .d.ts files from Flow source; its README says it is not meant as a tool for migrating away from Flow. Community converters exist, but the best known, Khan Academy's flow-to-ts, is archived.

Sources

Last reviewed 21 October 2026.