Restrictions and reserved syntax
This page lists unsupported syntax, reserved names and runtime requirements for .tsi files.
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.- Names starting with
__nolaare used by generated code. Declaring one can shadow a generated binding and break the program without a diagnostic. Avoid these names and use the public Nola syntax instead of calling generated helpers.
// 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 following forms are unsupported. The table shows the error to expect and, where available, the supported alternative.
| 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 |
plain parse error (NOLA1001) — infer is a keyword only before function at statement/export position |
infer function* (generator), a marker on a class method, or a bodiless infer function |
NOLA1004 — reserved |
fn(..) — the bare derive-all call |
NOLA1004 |
var .x = … — a var contextual binding |
NOLA1014 — write const .x or let .x (Contextual bindings) |
. on a destructuring pattern or a defaulted parameter |
NOLA1011 — use a plain identifier parameter |
a marker between a function’s name and its parameters — infer function name`…`() / function name`…`() |
NOLA1019 (reserved) / NOLA1007 — write the text as a context statement in the body |
an operator or an arrow after a value in a context statement — `total` a + b |
NOLA1020 — wrap the expression in parentheses |
a context statement outside a scope body — in a plain function, a callback, a static block, or as the unbraced body of an if or a loop |
NOLA2017 — no ask can carry it there; move it into the scope body, or add braces to the if or loop |
Other proposed forms also remain unsupported: abstract functions, type and interface intents, ask if, ask for, ask while, ask switch, and infer class methods. They produce a general parse error (NOLA1001) rather than a dedicated reserved-syntax diagnostic.
Runtimes
Section titled “Runtimes”- Node ≥ 22.18 is required to load
.tsialongside plain.tsfiles. The loader uses Node’s module hooks; running it directly with Bun or Deno is unsupported (NOLA3015). You can still use npm, pnpm, Yarn or Bun as your package manager, provided Node runs the program. See Node loader. - Server-side execution only. Importing
.tsiinto a client bundle fails withNOLA4001; running an ask in a browser raisesNOLA3013. Put the import in a server entry point, route handler or server action.
Not restrictions
Section titled “Not restrictions”The following are supported:
awaitinside an infer function — legal, for any ordinary promise.- Constructing an extractor at module level — legal and inert. Asking at module level — also legal: a top-level
askruns as its own<module>invocation (see ask). - 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