cli/tsc/README.md
This directory contains the typescript compiler and a small compiler host for the runtime snapshot.
The files in this directory are mostly from the TypeScript repository. We currently (unfortunately) have a rather manual process for upgrading TypeScript. It works like this currently:
So that might look something like this:
git clone https://github.com/denoland/TypeScript.git
cd typescript
git remote add upstream https://github.com/Microsoft/TypeScript
git fetch upstream
git checkout v3.9.7
git checkout -b branch_v3.9.7
git cherry pick <previous-release-branch-commit-we-did>
npm install
npx hereby
rsync built/local/typescript.js ~/src/deno/cli/tsc/00_typescript.js
rsync --exclude=protocol.d.ts --exclude=tsserverlibrary.d.ts --exclude=typescriptServices.d.ts built/local/*.d.ts ~/src/deno/cli/tsc/dts/
Currently only integrated with deno check, though in the future it will also be integrated with our LSP implementation.
In the CLI, we have a small abstraction over the tsc backend in
cli/tsc/mod.rs. Along with some shared types and functionality, the
main piece is the exec function, which takes a "request" to be served by the
typescript compiler and returns the result. This now has two different "backend"
which can serve the request – the current tsc, which runs in an isolate and
communicates via ops, and typescript-go which runs in a subprocess and uses IPC.
From a high level, the way the tsgo backend works is that we download a typescript-go binary from github releases into the deno cache dir. To actually interface with tsgo, we spawn it in a subprocess and write messages over stdin/stdout (similar to the Language Server Protocol). The format is a mixture of binary data (for the header and other protocol level details) followed by json encoded values for RPC calls. The rust implementation of the IPC protocol is in the deno_typescript_go_client_rust crate.
We currently maintain a fork of typescript-go with the following changes:
setTimeout. With node globals setTimeout returns an
object, and with deno globals it returns a number (just like the web
standard).deno.window, deno.worker, etc)