Restrictions and reserved syntax
Nola adds little and reserves a little more. This page is the complete list of what a .tsi file refuses today, and why.
Reserved words
Section titled “Reserved words”askandwithare reserved words in.tsi.askstays legal as a member or property name (obj.ask); using it as a plain identifier isNOLA1003.inferis contextual: a keyword only directly beforefunctionat statement or export position.T extends infer Uin a conditional type is untouched.__nolaand any identifier starting with__nolaare reserved.__nola.ask(…),__nola.intents.ExtractIntent(…)and friends are what the compiler emits — not an API you call.
// not-checked — WRONG: emitted code, not a user-facing APIexport infer function read(.doc: string) { const wrong = await __nola.ask(__nola.intents.ExtractIntent({ instruction: "the value" }), __frame); return wrong;}// read.tsi — RIGHTexport infer function read(.doc: string) { const v = ask ..`the value`<string>; return v;}Syntax that is reserved for a later version
Section titled “Syntax that is reserved for a later version”The grammar is shaped to accept these; today each one is a clear error rather than a silent misparse.
| You write | What happens |
|---|---|
async infer function f(…) |
parse error — an infer function is never async in source; await is already legal in its body |
export default infer function f(…) |
does not parse — export by name and import the name |
infer on a method, arrow function or function expression |
NOLA1004 — top-level function declarations only |
fn(..) — the bare derive-all call |
NOLA1004 |
const .x = … — a contextual binding inside a body |
NOLA1014 |
. on a destructuring pattern or a defaulted parameter |
NOLA1011 — use a plain identifier parameter |
the removed function name`()` form |
NOLA1007 — declare it with infer function |
Further language features are deferred and parse as reserved today: abstract functions, type and interface intents, ask if / ask for / ask while / ask switch, and class methods. They are listed here so you recognise the error; nothing on this site documents them as available.
Runtimes
Section titled “Runtimes”- Node ≥ 22 runs
.tsi. The loader is Node’s module-hooks API, which Bun and Deno do not run —bun --bun,bun src/main.tsanddeno runfail withNOLA3015. Any package manager is fine (bun install,bun run start,pnpm start,yarn start— thenolabin is a Node script); only the runtime must be Node. Built output runs anywhere Node does. - Server-only in v0. A client bundle that imports
.tsifails the build withNOLA4001; executing an ask in a browser isNOLA3013. Move the import behind a server boundary (SSR entry, route handler, server action).
Not restrictions
Section titled “Not restrictions”Things people assume are forbidden and are not:
awaitinside an infer function — legal, for any ordinary promise.- Constructing an extractor at module level — legal and inert; only
askis position-restricted. - Several contextual parameters on one function — legal; they compose into one block.
- Calling one infer function from another with
ask otherFn(…)— legal; that is how you compose them.
Next: nola.config.ts