Build
What's new
- Visual Studio Code project
- Strict null checks
let sn: string | null = null; // Ok let s: string = null; // error
- improved
Template Literal Types
type Color = "red" | "green" | "blue"; type HexColor<T extends Color> = `#${string}`;
- Public, private, and protected modifiers
class Point { private x: number; #y: number; } const p = new Point(); p.x // access error p.#y // error
- Class from Tuple
class Point { x: number; y: number; } class Line { constructor(public start: Point, public end: Point) { } } const l = new Line({ x: 0, y: 1 }, { x: 1.0, y: 2.0 });
- Compile-time
ifs
function isArray<T extends unknown[]>(value: T): value is T { return true; } function gen<T>(t: T) { if (isArray(t)) { return t.length.toString(); } return "int"; } const v1 = gen<i32>(23); // result: int const v2 = gen<string[]>([]); // result: 0
-
Migrated to LLVM 19.1.3
-
improved
generating debug informationmore info here: Wiki:How-To
tsc --di --opt_level=0 --emit=exe example.tsPlanning
- Migrating to LLVM 19.1.3
- Shared libraries
- JavaScript Built-in classes library
Demo
Try it
Chat Room
Want to chat with other members of the TypeScriptCompiler community?
Example
abstract class Department { constructor(public name: string) {} printName(): void { print("Department name: " + this.name); } abstract printMeeting(): void; // must be implemented in derived classes } class AccountingDepartment extends Department { constructor() { super("Accounting and Auditing"); // constructors in derived classes must call super() } printMeeting(): void { print("The Accounting Department meets each Monday at 10am."); } generateReports(): void { print("Generating accounting reports..."); } } function main() { let department: Department; // ok to create a reference to an abstract type department = new AccountingDepartment(); // ok to create and assign a non-abstract subclass department.printName(); department.printMeeting(); //department.generateReports(); // error: department is not of type AccountingDepartment, cannot access generateReports }
Run
tsc --emit=jit --opt --shared-libs=TypeScriptRuntime.dll example.ts
Result
Department name: Accounting and Auditing
The Accounting Department meets each Monday at 10am.
Run as JIT
- with Garbage collection
tsc --emit=jit --opt --shared-libs=TypeScriptRuntime.dll hello.ts
- without Garbage collection
tsc --emit=jit --nogc hello.ts
File hello.ts
function main() { print("Hello World!"); }
Result
Compile as Binary Executable
On Windows
File tsc-compile.bat
set FILENAME=%1 set GC_LIB_PATH=C:\dev\TypeScriptCompiler\__build\gc\msbuild\x64\release\Release set LLVM_LIB_PATH=C:\dev\TypeScriptCompiler\__build\llvm\msbuild\x64\release\Release\lib set TSC_LIB_PATH=C:\dev\TypeScriptCompiler\__build\tsc\windows-msbuild-release\lib set TSCEXEPATH=C:\dev\TypeScriptCompiler\__build\tsc\windows-msbuild-release\bin %TSCEXEPATH%\tsc.exe --opt --emit=exe %FILENAME%.ts
Compile
Run
Result
On Linux (Ubuntu 20.04 and 22.04)
File tsc-compile.sh
FILENAME=$1 export TSC_LIB_PATH=~/dev/TypeScriptCompiler/__build/tsc/linux-ninja-gcc-release/lib export LLVM_LIB_PATH=~/dev/TypeScriptCompiler/3rdParty/llvm/release/lib export GC_LIB_PATH=~/dev/TypeScriptCompiler/3rdParty/gc/release TSCEXEPATH=~/dev/TypeScriptCompiler/__build/tsc/linux-ninja-gcc-release/bin $TSCEXEPATH/tsc --emit=exe $FILENAME.ts --relocation-model=pic
Compile
sh -f tsc-compile.sh hello
Run
Result
Compiling as WASM
On Windows
File tsc-compile-wasm.bat
set FILENAME=%1 set GC_LIB_PATH=C:\dev\TypeScriptCompiler\__build\gc\msbuild\x64\release\Release set LLVM_LIB_PATH=C:\dev\TypeScriptCompiler\__build\llvm\msbuild\x64\release\Release\lib set TSC_LIB_PATH=C:\dev\TypeScriptCompiler\__build\tsc\windows-msbuild-release\lib C:\dev\TypeScriptCompiler\__build\tsc\windows-msbuild-release\bin\tsc.exe --emit=exe --nogc -mtriple=wasm32-unknown-unknown %FILENAME%.ts
Compile
tsc-compile-wasm.bat hello
Run run.html
<!DOCTYPE html> <html> <head></head> <body> <script type="module"> let buffer; let buffer32; let buffer64; let bufferF64; let heap; let heap_base, heap_end, stack_low, stack_high; const allocated = []; const allocatedSize = (addr) => { return allocated["" + addr]; }; const setAllocatedSize = (addr, newSize) => { allocated["" + addr] = newSize; }; const expand = (addr, newSize) => { const aligned_newSize = newSize + (4 - (newSize % 4)) const end = addr + allocatedSize(addr); const newEnd = addr + aligned_newSize; for (const allocatedAddr in allocated) { const beginAllocatedAddr = parseInt(allocatedAddr); const endAllocatedAddr = beginAllocatedAddr + allocated[allocatedAddr]; if (beginAllocatedAddr != addr && addr < endAllocatedAddr && newEnd > beginAllocatedAddr) { return false; } } setAllocatedSize(addr, aligned_newSize); if (addr + aligned_newSize > heap) heap = addr + aligned_newSize; return true; }; const endOf = (addr) => { while (buffer[addr] != 0) { addr++; if (addr > heap_end) throw "out of memory boundary"; }; return addr; }; const strOf = (addr) => String.fromCharCode(...buffer.slice(addr, endOf(addr))); const copyStr = (dst, src) => { while (buffer[src] != 0) buffer[dst++] = buffer[src++]; buffer[dst] = 0; return dst; }; const ncopy = (dst, src, count) => { while (count-- > 0) buffer[dst++] = buffer[src++]; return dst; }; const append = (dst, src) => copyStr(endOf(dst), src); const cmp = (addrL, addrR) => { while (buffer[addrL] != 0) { if (buffer[addrL] != buffer[addrR]) break; addrL++; addrR++; } return buffer[addrL] - buffer[addrR]; }; const prn = (str, addr) => { for (let i = 0; i < str.length; i++) buffer[addr++] = str.charCodeAt(i); buffer[addr] = 0; return addr; }; const clear = (addr, size, val) => { for (let i = 0; i < size; i++) buffer[addr++] = val; }; const aligned_alloc = (size) => { const aligned_size = size + (4 - (size % 4)); if ((heap + aligned_size) > heap_end) throw "out of memory"; setAllocatedSize(heap, aligned_size); const heapCurrent = heap; heap += aligned_size; return heapCurrent; }; const free = (addr) => delete allocated["" + addr]; const realloc = (addr, size) => { if (!expand(addr, size)) { const newAddr = aligned_alloc(size); ncopy(newAddr, addr, allocatedSize(addr)); free(addr); return newAddr; } return addr; } const envObj = { memory: new WebAssembly.Memory({ initial: 256 }), table: new WebAssembly.Table({ initial: 0, element: 'anyfunc', }), fmod: (arg1, arg2) => arg1 % arg2, sqrt: (arg1) => Math.sqrt(arg1), floor: (arg1) => Math.floor(arg1), pow: (arg1, arg2) => Math.pow(arg1, arg2), fabs: (arg1) => Math.abs(arg1), _assert: (msg, file, line) => console.assert(false, strOf(msg), "| file:", strOf(file), "| line:", line, " DBG:", path), puts: (arg) => output += strOf(arg) + '\n', strcpy: copyStr, strcat: append, strcmp: cmp, strlen: (addr) => endOf(addr) - addr, malloc: aligned_alloc, realloc: realloc, free: free, memset: (addr, size, val) => clear(addr, size, val), atoi: (addr, rdx) => parseInt(strOf(addr), rdx), atof: (addr) => parseFloat(strOf(addr)), sprintf_s: (addr, sizeOfBuffer, format, ...args) => { const formatStr = strOf(format); switch (formatStr) { case "%d": prn(buffer32[args[0] >> 2].toString(), addr); break; case "%g": prn(bufferF64[args[0] >> 3].toString(), addr); break; case "%llu": prn(buffer64[args[0] >> 3].toString(), addr); break; default: throw "not implemented"; } return 0; }, } const config = { env: envObj, }; WebAssembly.instantiateStreaming(fetch("./hello.wasm"), config) .then(results => { const { main, __wasm_call_ctors, __heap_base, __heap_end, __stack_low, __stack_high } = results.instance.exports; buffer = new Uint8Array(results.instance.exports.memory.buffer); buffer32 = new Uint32Array(results.instance.exports.memory.buffer); buffer64 = new BigUint64Array(results.instance.exports.memory.buffer); bufferF64 = new Float64Array(results.instance.exports.memory.buffer); heap = heap_base = __heap_base, heap_end = __heap_end, stack_low = __stack_low, stack_high = __stack_high; try { if (__wasm_call_ctors) __wasm_call_ctors(); main(); } catch (e) { console.error(e); } }); </script> </body> </html>
Build
On Windows
Requirements:
Visual Studio 2022- 512GB of free space on disk
First, precompile dependencies
cd TypeScriptCompiler
prepare_3rdParty.bat To build TSC binaries:
cd TypeScriptCompiler\tsc
config_tsc_release.bat
build_tsc_release.batOn Linux (Ubuntu 20.04 and 22.04)
Requirements:
GCCorClang- 512GB of free space on disk
- sudo apt-get install
libtinfo-dev
First, precompile dependencies
chmod +x *.sh cd ~/TypeScriptCompiler ./prepare_3rdParty.sh
To build TSC binaries:
cd ~/TypeScriptCompiler/tsc chmod +x *.sh ./config_tsc_release.sh ./build_tsc_release.sh


