WebAssembly
The tsc_rs_wasm crate compiles the tsc-rs parser, binder, type checker and emitter to WebAssembly. It runs in a browser, in a worker, at the edge, or anywhere else that can instantiate a Wasm module. The playground on this site is that build.
API#
Three functions are exported.
function compile(source: string, options?: CompileOptions): CompileResult;
function validate(source: string, options?: CompileOptions): Diagnostic[];
function version(): string;
compileparses and emits. It returns the JavaScript and the parse diagnostics. It does not type-check.validateparses, binds and type-checks one file, and returns all diagnostics. It does not emit.versionreturns the tsc-rs version.
CompileOptions#
| Option | Type | Meaning |
|---|---|---|
target |
string | ECMAScript target: es5, es2015 to es2025, esnext. Default esnext |
module |
string | commonjs, amd, umd, system, es2015, es2020, es2022, esnext, node16, nodenext |
jsx |
string | react, react-jsx, react-jsxdev, preserve |
sourceMap |
boolean | Return a source map |
declaration |
boolean | Return a .d.ts |
strict |
boolean | Enable strict mode |
fileName |
string | Name used for diagnostics and source maps. Default input.ts. Use a .tsx name for JSX |
CompileResult#
interface CompileResult {
js: string;
sourceMap?: string;
declaration?: string;
diagnostics: Diagnostic[];
}
interface Diagnostic {
message: string;
line: number;
column: number;
severity: string;
code?: number;
}
Usage#
import init, { compile, validate, version } from "./pkg/tsc-rs-wasm.js";
await init();
const result = compile("const x: number = 42;", { target: "es2020" });
console.log(result.js);
const diagnostics = validate('const x: number = "oops";', { strict: true });
console.log(diagnostics);
// [{ message: "Type 'string' is not assignable to type 'number'.", line: 1, column: 7, severity: "error", code: 2322 }]
init() fetches and instantiates tsc-rs-wasm_bg.wasm from next to the JavaScript file. Serve the .wasm file with the application/wasm content type.
Build#
You need wasm-pack and the Wasm target:
cargo install wasm-pack
rustup target add wasm32-unknown-unknown
The crate is not yet listed in the workspace members, so Cargo refuses to build it in place. Add it to the members array in the root Cargo.toml:
[workspace]
members = [
# ...
"crates/tsc_rs_wasm",
]
Then build:
cd crates/tsc_rs_wasm
wasm-pack build --target web --out-dir pkg --out-name tsc-rs-wasm --no-opt
--no-opt skips the bundled wasm-opt pass, which rejects the bulk-memory operations that current Rust emits. To shrink the binary, run wasm-opt yourself with the newer features enabled:
wasm-opt pkg/tsc-rs-wasm_bg.wasm -o pkg/tsc-rs-wasm_bg.wasm -Os --all-features
The result is about 4.5 MB, or about 1.6 MB with gzip.
What it does not do#
- One file at a time. There is no file system and no module resolution, so imports are not followed.
- No full standard library. Type checking uses the built-in fallback declarations, not the complete
lib.d.ts, and no@typespackages. Code that depends on library or framework types can report errors the command line compiler would not. - Not on npm. The package is not published; build it and ship the
pkgdirectory with your application.
Content Security Policy#
Instantiating WebAssembly needs 'wasm-unsafe-eval' in the script-src directive of a strict Content Security Policy.
Found a mistake on this page? Open an issue on GitHub.