···312312313313Note that `Caption` won't exist as a separate def—the abstraction is erased in the output.
314314315315+### Scalars
316316+317317+TypeSpec scalars let you create named types with constraints. **By default, scalars create standalone defs** (like models):
318318+319319+```typescript
320320+import "@typelex/emitter";
321321+322322+namespace com.example {
323323+ model Main {
324324+ handle?: Handle;
325325+ bio?: Bio;
326326+ }
327327+328328+ @maxLength(50)
329329+ scalar Handle extends string;
330330+331331+ @maxLength(256)
332332+ @maxGraphemes(128)
333333+ scalar Bio extends string;
334334+}
335335+```
336336+337337+This creates three defs: `main`, `handle`, and `bio`:
338338+339339+```json
340340+{
341341+ "id": "com.example",
342342+ "defs": {
343343+ "main": {
344344+ "type": "object",
345345+ "properties": {
346346+ "handle": { "type": "ref", "ref": "#handle" },
347347+ "bio": { "type": "ref", "ref": "#bio" }
348348+ }
349349+ },
350350+ "handle": {
351351+ "type": "string",
352352+ "maxLength": 50
353353+ },
354354+ "bio": {
355355+ "type": "string",
356356+ "maxLength": 256,
357357+ "maxGraphemes": 128
358358+ }
359359+ }
360360+}
361361+```
362362+363363+Use `@inline` to expand a scalar inline instead:
364364+365365+```typescript
366366+import "@typelex/emitter";
367367+368368+namespace com.example {
369369+ model Main {
370370+ handle?: Handle;
371371+ }
372372+373373+ @inline
374374+ @maxLength(50)
375375+ scalar Handle extends string;
376376+}
377377+```
378378+379379+Now `Handle` is expanded inline (no separate def):
380380+381381+```json
382382+// ...
383383+"properties": {
384384+ "handle": { "type": "string", "maxLength": 50 }
385385+}
386386+// ...
387387+```
388388+315389## Top-Level Lexicon Types
316390317391TypeSpec uses `model` for almost everything. Decorators specify what kind of Lexicon type it becomes.
···905979906980## Defaults and Constants
907981908908-### Defaults
982982+### Property Defaults
983983+984984+You can set default values on properties:
909985910986```typescript
911987import "@typelex/emitter";
···919995```
920996921997Maps to: `{"default": 1}`, `{"default": "en"}`
998998+999999+### Type Defaults
10001000+10011001+You can also set defaults on scalar and union types using the `@default` decorator:
10021002+10031003+```typescript
10041004+import "@typelex/emitter";
10051005+10061006+namespace com.example {
10071007+ model Main {
10081008+ mode?: Mode;
10091009+ priority?: Priority;
10101010+ }
10111011+10121012+ @default("standard")
10131013+ scalar Mode extends string;
10141014+10151015+ @default(1)
10161016+ @closed
10171017+ @inline
10181018+ union Priority { 1, 2, 3 }
10191019+}
10201020+```
10211021+10221022+This creates a default on the type definition itself:
10231023+10241024+```json
10251025+{
10261026+ "defs": {
10271027+ "mode": {
10281028+ "type": "string",
10291029+ "default": "standard"
10301030+ }
10311031+ }
10321032+}
10331033+```
10341034+10351035+For unions with token references, pass the model directly:
10361036+10371037+```typescript
10381038+import "@typelex/emitter";
10391039+10401040+namespace com.example {
10411041+ model Main {
10421042+ eventType?: EventType;
10431043+ }
10441044+10451045+ @default(InPerson)
10461046+ union EventType { Hybrid, InPerson, Virtual, string }
10471047+10481048+ @token model Hybrid {}
10491049+ @token model InPerson {}
10501050+ @token model Virtual {}
10511051+}
10521052+```
10531053+10541054+This resolves to the fully-qualified token NSID:
10551055+10561056+```json
10571057+{
10581058+ "eventType": {
10591059+ "type": "string",
10601060+ "knownValues": [
10611061+ "com.example#hybrid",
10621062+ "com.example#inPerson",
10631063+ "com.example#virtual"
10641064+ ],
10651065+ "default": "com.example#inPerson"
10661066+ }
10671067+}
10681068+```
10691069+10701070+**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:
10711071+10721072+```typescript
10731073+@default("standard")
10741074+scalar Mode extends string;
10751075+10761076+model Main {
10771077+ mode?: Mode = "custom"; // ERROR: Conflicting defaults!
10781078+}
10791079+```
10801080+10811081+Solutions:
10821082+1. Make the defaults match: `mode?: Mode = "standard"`
10831083+2. Mark the type `@inline`: Allows property-level defaults
10841084+3. Remove the property default: Uses the type's default
92210859231086### Constants
9241087
+40
packages/emitter/lib/decorators.tsp
···163163extern dec errors(target: unknown, ...errors: unknown[]);
164164165165/**
166166+ * Forces a model, scalar, or union to be inlined instead of creating a standalone def.
167167+ * By default, named types create separate definitions with references.
168168+ * Use @inline to expand the type inline at each usage site.
169169+ *
170170+ * @example Inline model
171171+ * ```typespec
172172+ * @inline
173173+ * model Caption {
174174+ * text?: string;
175175+ * }
176176+ *
177177+ * model Main {
178178+ * captions?: Caption[]; // Expands inline, no separate "caption" def
179179+ * }
180180+ * ```
181181+ *
182182+ * @example Inline scalar
183183+ * ```typespec
184184+ * @inline
185185+ * @maxLength(50)
186186+ * scalar Handle extends string;
187187+ *
188188+ * model Main {
189189+ * handle?: Handle; // Expands to { type: "string", maxLength: 50 }
190190+ * }
191191+ * ```
192192+ *
193193+ * @example Inline union
194194+ * ```typespec
195195+ * @inline
196196+ * union Status { "active", "inactive", string }
197197+ *
198198+ * model Main {
199199+ * status?: Status; // Expands inline with knownValues
200200+ * }
201201+ * ```
202202+ */
203203+extern dec inline(target: unknown);
204204+205205+/**
166206 * Specifies a default value for a scalar or union definition.
167207 * Only valid on standalone scalar or union defs (not @inline).
168208 * The value must match the underlying type (string, integer, or boolean).
···11+import "@typelex/emitter";
22+33+namespace community.lexicon.calendar.event {
44+ /** A calendar event. */
55+ @rec("tid")
66+ model Main {
77+ /** The name of the event. */
88+ @required
99+ name: string;
1010+1111+ /** The description of the event. */
1212+ description?: string;
1313+1414+ /** Client-declared timestamp when the event was created. */
1515+ @required
1616+ createdAt: datetime;
1717+1818+ /** Client-declared timestamp when the event starts. */
1919+ startsAt?: datetime;
2020+2121+ /** Client-declared timestamp when the event ends. */
2222+ endsAt?: datetime;
2323+2424+ /** The attendance mode of the event. */
2525+ mode?: Mode;
2626+2727+ /** The status of the event. */
2828+ status?: Status;
2929+3030+ /** The locations where the event takes place. */
3131+ locations?: (
3232+ | Uri
3333+ | community.lexicon.location.address.Main
3434+ | community.lexicon.location.fsq.Main
3535+ | community.lexicon.location.geo.Main
3636+ | community.lexicon.location.hthree.Main
3737+ )[];
3838+3939+ /** URIs associated with the event. */
4040+ uris?: Uri[];
4141+ }
4242+4343+ /** The mode of the event. */
4444+ @default(Inperson)
4545+ union Mode {
4646+ Hybrid,
4747+ Inperson,
4848+ Virtual,
4949+ string,
5050+ }
5151+5252+ /** A virtual event that takes place online. */
5353+ @token
5454+ model Virtual {}
5555+5656+ /** An in-person event that takes place offline. */
5757+ @token
5858+ model Inperson {}
5959+6060+ /** A hybrid event that takes place both online and offline. */
6161+ @token
6262+ model Hybrid {}
6363+6464+ /** The status of the event. */
6565+ @default(Scheduled)
6666+ union Status {
6767+ Cancelled,
6868+ Planned,
6969+ Postponed,
7070+ Rescheduled,
7171+ Scheduled,
7272+ string,
7373+ }
7474+7575+ /** The event has been created, but not finalized. */
7676+ @token
7777+ model Planned {}
7878+7979+ /** The event has been created and scheduled. */
8080+ @token
8181+ model Scheduled {}
8282+8383+ /** The event has been rescheduled. */
8484+ @token
8585+ model Rescheduled {}
8686+8787+ /** The event has been cancelled. */
8888+ @token
8989+ model Cancelled {}
9090+9191+ /** The event has been postponed and a new start date has not been set. */
9292+ @token
9393+ model Postponed {}
9494+9595+ /** A URI associated with the event. */
9696+ model Uri {
9797+ @required
9898+ uri: uri;
9999+100100+ /** The display name of the URI. */
101101+ name?: string;
102102+ }
103103+}
104104+105105+// --- Externals ---
106106+107107+@external
108108+namespace community.lexicon.location.address {
109109+ model Main {}
110110+}
111111+112112+@external
113113+namespace community.lexicon.location.fsq {
114114+ model Main {}
115115+}
116116+117117+@external
118118+namespace community.lexicon.location.geo {
119119+ model Main {}
120120+}
121121+122122+@external
123123+namespace community.lexicon.location.hthree {
124124+ model Main {}
125125+}