Guide

Language guide

If it's core TypeScript, it probably compiles. Here's the shape of what's supported — and the deliberate sharp edges worth knowing before you lean on them.

Numbers: JS-faithful by default, sized when you want

A bare : number is a JS-faithful IEEE-754 double, so untyped arithmetic matches JavaScript exactly — 0.1 + 0.2 yields 0.30000000000000004, 10 / 3 yields 3.3333333333333335. Reach for a sized integer type (int8int64, uint8uint64), or a JSDoc width override, when you want real machine-integer semantics.

const ratio: number = 0.1 + 0.2;   // 0.30000000000000004 (JS-faithful)
const q: number = 10 / 3;          // 3.3333333333333335
let count: int32 = 7;              // opt-in integer semantics: 7 / 2 -> 3
/** @type {uint8} */
let byte = 255;                    // exact width via JSDoc: 255 + 1 -> 0

Generics & interfaces

Generic functions, interfaces and classes work, including object/interface/class type arguments and <T extends X> constraints. A function's type arguments are inference-only today (no explicit identity<number>(5)).

function identity<T>(x: T): T {
  return x;
}

console.log(identity(42));       // 42
console.log(identity("hello"));  // hello

interface Box<T> {
  value: T;
}

const boxedNumber: Box<number> = { value: 7 };
const boxedString: Box<string> = { value: "seven" };

Classes & OOP

Classes, inheritance, #private fields, getters/setters, static members and [Symbol.iterator] all work. Parameter properties (constructor(public x: number)) and the readonly field modifier aren't parsed yet — declare the field explicitly. Built-in types aren't valid extends targets (no class X extends Error).

Async / await

Full marks — async/await and Promise are at 100% coverage. Concurrency is cooperative: exactly one fiber runs at a time per thread, no preemption, same single-threaded model as JS. Real parallelism lives one level up in worker_threads, which spawns actual pthreads.

const r = await fetch('http://127.0.0.1:8765/get')

console.log(r.status)          // 200
console.log(r.ok)              // true

interface Ip { origin: string }

// .json() parses the body straight into a declared type
const data = r.json() as Ip
console.log(data.origin)

Unions & narrowing

Union types allow scalar members and object members (one, or ≥2 as a discriminated union with a first-position string-literal tag). Flow narrowing works for a union local or field — typeof, truthiness, == null, tag === "literal", with if/else and early return.

Modules

Named import/export plus static CommonJS require('<literal>') work. There's no real linker: every module you touch is flattened into one AST and one main(). Imported files run their top-level code once, in dependency order; only import cycles are held to declarations-only.

What's deliberately out

  • Proxy / Reflect — dynamic property intercept.
  • Decorators — need metadata reflection.
  • eval — an opt-in embedded-engine path, not started.
  • Runtime property add/delete — objects are fixed-shape heap structs.