Three neighbors of TypeScript remain worth knowing: a competitor, a way to use TypeScript without its syntax, and a language that borrows its syntax for WebAssembly.
| Option | Source files | Checked by | License | Best for |
|---|---|---|---|---|
| TypeScript 7.0 | .ts | tsc | Apache-2.0 | Almost every project |
| Flow 0.331 340,866 | .js with // @flow | flow (Rust) | MIT | Meta-style React 7,897 codebases |
| JSDoc-only | Plain .js | tsc with checkJs | Apache-2.0 | Libraries without a build step |
| AssemblyScript 0.28 | .ts (own types) | asc | Apache-2.0 | Hot numeric code as WebAssembly |
Flow
Meta's Flow (https://github.com/facebook/flow 22,299 ) (22k stars) checks "millions of files" inside Meta. Its syntax is close to TypeScript's, but objects are exact by default and it adds component, renders and match syntax. Install flow-bin, run flow init, and strip annotations with @babel/preset-flow or flow-remove-types. Since 2021 Flow has put Meta's own codebase first, so outside Meta choose it only to maintain existing Flow code.
JSDoc-only
The same tsc checks types written in comments (Declaration Files), so files run unchanged in browsers and Node.js 2,131 and no source maps are needed. You pay with verbose syntax. Node.js type stripping (Installing and Running) now weakens the no-build argument for .ts files.
AssemblyScript
AssemblyScript (https://github.com/AssemblyScript/assemblyscript 18,028 ) (18k stars) compiles a variant of TypeScript to WebAssembly through Binaryen 8,645 . Types are machine types (i32, i64, f64), and dynamic features such as any and union types are not supported:
export function fib(n: i32): i64 {
let a: i64 = 0, b: i64 = 1;
for (let i = 0; i < n; i++) {
const t = a + b;
a = b;
b = t;
}
return a;
}$ node -e "import('./build/fib.js').then(m => console.log(m.fib(90), m.fib(3.9)))"
2880067194370816120n 2nThe optimized fib.wasm is 90 bytes; the bindings map i64 to bigint and truncate 3.9 to 3. Use AssemblyScript for computation, not DOM code, which still needs JavaScript.