Language overview
ChadScript compiles a subset of TypeScript. The subset is not a dialect: every accepted program is valid TypeScript with the same meaning, and it runs unchanged under Node. What changes is the set of programs the compiler agrees to build.
The rules in one screen
- It must typecheck at maximum strictness.
strict,noUncheckedIndexedAccess,exactOptionalPropertyTypes,noImplicitOverrideandnoPropertyAccessFromIndexSignatureare always on, with zero diagnostics allowed. Array reads areT | undefined, so you narrow or default them (xs[i] ?? 0). - Every construct must be one the compiler supports. The accepted subset lists them, straight from the compiler's own tables. Anything else is rejected with a code and a rewrite.
- Objects keep the shape they were created with. No adding or deleting properties, no prototype edits. Optional fields (
x?: T) are how you model "maybe present". - Types decide the machine layout.
number,stringandbooleanare stored directly. A union of different kinds (number | string) carries a small type tag, and you narrow it (typeof x === "number") before most operations. - Strings are ASCII for now. A non-ASCII string literal is rejected at compile time, and non-ASCII text arriving at run time (a command-line argument, a file read as text, socket data) stops the program with an error rather than being measured or indexed differently from Node. Within ASCII, every string operation (
s[i],for...of,<,charCodeAt) is exact.
Topics
Every example on these pages is a file in docs/examples/. The test suite compiles each one and checks that the binary's output matches Node's at -O0 and -O2, and that the output shown on the page is what Node prints.
| Topic | Covers |
|---|---|
| Modules and imports | named, default, namespace and type-only imports; re-exports; packages |
| Classes and interfaces | inheritance, super, override, instanceof, interface dispatch |
| Unions and narrowing | typeof, ===, Array.isArray, discriminated unions, ?? |
| Generics | generic functions and classes, constraints, erasure |
| Closures | captured mutable variables, per-iteration bindings, higher-order functions |
| Map and Set | counting, iteration order, spreading keys, new Map from pairs |
| async / await | Node's microtask ordering, Promise.all, new Promise, timers |
| Errors | throw, try/catch/finally, Error classes, uncaught errors |
| JSON | typed JSON.parse with shape checking, JSON.stringify, cycles |
| node:fs and node:path | sync and promise file APIs, path helpers, process.argv |
| console.log | util.inspect formatting, format directives, String() and templates |
Not in the subset
Permanently out, because they need a JavaScript engine rather than a compiler: any, eval and new Function, prototype mutation, adding or deleting properties at run time, Proxy, CommonJS, and packages that ship only JavaScript. Programs that need them should run on Node.
Not yet, planned: regular expressions, Date instances, optional and default parameters, getters and setters, toFixed, .then() on promises, classes that extend Error, generics instantiated with arrays or functions (wrap them in an object), optional chains longer than one ?., and Map/Set keyed by a union. Each is rejected today with a specific code; see the limitations and the roadmap.
Next: Modules and imports.