···
Note that `Caption` won't exist as a separate def—the abstraction is erased in the output.
317
+
TypeSpec scalars let you create named types with constraints. **By default, scalars create standalone defs** (like models):
320
+
import "@typelex/emitter";
322
+
namespace com.example {
329
+
scalar Handle extends string;
333
+
scalar Bio extends string;
337
+
This creates three defs: `main`, `handle`, and `bio`:
341
+
"id": "com.example",
346
+
"handle": { "type": "ref", "ref": "#handle" },
347
+
"bio": { "type": "ref", "ref": "#bio" }
357
+
"maxGraphemes": 128
363
+
Use `@inline` to expand a scalar inline instead:
366
+
import "@typelex/emitter";
368
+
namespace com.example {
375
+
scalar Handle extends string;
379
+
Now `Handle` is expanded inline (no separate def):
384
+
"handle": { "type": "string", "maxLength": 50 }
## Top-Level Lexicon Types
TypeSpec uses `model` for almost everything. Decorators specify what kind of Lexicon type it becomes.
···
## Defaults and Constants
982
+
### Property Defaults
984
+
You can set default values on properties:
import "@typelex/emitter";
···
Maps to: `{"default": 1}`, `{"default": "en"}`
1001
+
You can also set defaults on scalar and union types using the `@default` decorator:
1004
+
import "@typelex/emitter";
1006
+
namespace com.example {
1009
+
priority?: Priority;
1012
+
@default("standard")
1013
+
scalar Mode extends string;
1018
+
union Priority { 1, 2, 3 }
1022
+
This creates a default on the type definition itself:
1029
+
"default": "standard"
1035
+
For unions with token references, pass the model directly:
1038
+
import "@typelex/emitter";
1040
+
namespace com.example {
1042
+
eventType?: EventType;
1045
+
@default(InPerson)
1046
+
union EventType { Hybrid, InPerson, Virtual, string }
1048
+
@token model Hybrid {}
1049
+
@token model InPerson {}
1050
+
@token model Virtual {}
1054
+
This resolves to the fully-qualified token NSID:
1061
+
"com.example#hybrid",
1062
+
"com.example#inPerson",
1063
+
"com.example#virtual"
1065
+
"default": "com.example#inPerson"
1070
+
**Important:** When a scalar or union creates a standalone def (not `@inline`), property-level defaults must match the type's `@default`. Otherwise you'll get an error:
1073
+
@default("standard")
1074
+
scalar Mode extends string;
1077
+
mode?: Mode = "custom"; // ERROR: Conflicting defaults!
1082
+
1. Make the defaults match: `mode?: Mode = "standard"`
1083
+
2. Mark the type `@inline`: Allows property-level defaults
1084
+
3. Remove the property default: Uses the type's default
Use `@readOnly` with a default: