Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
41 commits
Select commit Hold shift + click to select a range
638a365
feat(compiler): allow declarations to be used as expressions
timotheeguerin Jun 18, 2026
053d3ff
fix(html-program-viewer): configure rendering for new expression prop…
timotheeguerin Jun 18, 2026
0b7d1ea
test(compiler): use expect and flatten top-level describe in decl-exp…
timotheeguerin Jun 18, 2026
0ceaad6
docs: add html-program-viewer changelog and clarify compiler changelo…
timotheeguerin Jun 18, 2026
f8ebdb7
fix(compiler): don't flatten keyword-form unions used as `|` operands
timotheeguerin Jun 18, 2026
f18990d
test(compiler): expand coverage for declarations as expressions
timotheeguerin Jun 18, 2026
44e5e41
fix(compiler): correct type names for declaration expressions
timotheeguerin Jun 18, 2026
9c2aaf0
Add syntax highlighting for declarations in expression position
timotheeguerin Jun 19, 2026
8262855
Update language spec grammar for declarations in expression position
timotheeguerin Jun 19, 2026
75ef483
fix: handle declaration expressions in emitters and versioning
timotheeguerin Jun 19, 2026
e3ecdd7
Merge remote-tracking branch 'upstream/main' into decl-expr
timotheeguerin Jun 22, 2026
843db66
refactor(compiler): use dedicated AST nodes for declaration expressions
timotheeguerin Jun 24, 2026
03f837d
feat(compiler): support inline and augment decorators on declaration …
timotheeguerin Jun 25, 2026
0c57447
feat(compiler): declaration expressions in decorator arguments, doc c…
timotheeguerin Jun 26, 2026
d640056
Refine declaration expressions: parser recovery, typekit, printer, docs
timotheeguerin Jun 26, 2026
dbbf0de
Gate declaration expressions behind declaration-expressions feature flag
timotheeguerin Jun 26, 2026
8495a48
Fix model is issue
timotheeguerin Jun 29, 2026
f7822f3
feat(compiler): break and indent decorators/doc comments on wide decl…
timotheeguerin Jun 30, 2026
a34aaee
Merge remote-tracking branch 'upstream/main' into decl-expr
timotheeguerin Jun 30, 2026
0bfae19
Format
timotheeguerin Jun 30, 2026
7ff1415
Format
timotheeguerin Jun 30, 2026
62f14a8
fix test
timotheeguerin Jun 30, 2026
5d4825e
test: add features option to Tester for enabling compiler features
timotheeguerin Jul 10, 2026
6dd3521
Merge remote-tracking branch 'upstream/main' into decl-expr
timotheeguerin Jul 15, 2026
b0c8f36
Merge branch 'main' into decl-expr
timotheeguerin Jul 28, 2026
8a8682a
fix(graphql): set required expression field when creating replacement…
timotheeguerin Jul 29, 2026
537dd0b
test(compiler): fix indentation in declaration expression formatter t…
timotheeguerin Jul 30, 2026
9fbccfd
docs(graphql): add changelog entry for scalar expression field fix
timotheeguerin Jul 30, 2026
41ad6b8
Merge branch 'main' into decl-expr
timotheeguerin Jul 30, 2026
3d09a5b
Merge upstream/main into decl-expr
timotheeguerin Aug 5, 2026
02ca05c
Merge branch 'main' into decl-expr
timotheeguerin Aug 28, 2026
79c30c8
Potential fix for pull request finding
timotheeguerin Aug 28, 2026
7053830
fix: gate declaration expressions behind feature flag error
timotheeguerin Sep 3, 2026
a947f0b
Merge remote-tracking branch 'upstream/main' into decl-expr
timotheeguerin Sep 3, 2026
8407316
Merge remote-tracking branch 'origin/decl-expr' into decl-expr
timotheeguerin Sep 3, 2026
68a4502
Update ModelDeclarationExpression syntax for heritage
timotheeguerin Sep 3, 2026
f55b400
Merge remote-tracking branch 'upstream/main' into decl-expr
timotheeguerin Sep 4, 2026
35e2e7b
Merge remote-tracking branch 'origin/decl-expr' into decl-expr
timotheeguerin Sep 4, 2026
c331435
fix: address review feedback on declaration expressions
timotheeguerin Sep 4, 2026
df03591
fix: reject anonymous declarations in typekit create
timotheeguerin Sep 4, 2026
9076246
Merge remote-tracking branch 'upstream/main' into decl-expr
timotheeguerin Sep 4, 2026
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Original file line number Diff line number Diff line change
@@ -0,0 +1,29 @@
---
changeKind: feature
packages:
- "@typespec/compiler"
---

Allow `model`, `enum`, `union`, and `scalar` declarations to be used as expressions. A declaration used in expression position has its corresponding type marked with `expression: true` and is not registered in the enclosing namespace. It may be named or anonymous (in which case it has no name).

This is an experimental feature that must be opted into by adding `declaration-expressions` to the `features` list in `tspconfig.yaml`; using a declaration expression without it reports a `declaration-expression-disabled` error.

They can be used anywhere an expression is expected, including aliases, model properties, decorator arguments, template arguments, function/call arguments, and tuples.

`model`, `scalar`, and `union` declaration expressions support the same `extends` clause as their statement form (union `extends` additionally requires the `union-extends` feature).

```tsp
alias Foo = enum {
a,
b,
};

model Bar {
status: enum { active, inactive };
unit: scalar extends string;
inner: model Inner { x: string };
}

@Versioning.versioned(enum Versions { v1, v2 })
namespace MyService;
```
16 changes: 16 additions & 0 deletions .chronus/changes/decl-expr-decorators-2026-4-18-0-0-2.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,16 @@
---
changeKind: feature
packages:
- "@typespec/compiler"
---

Allow decorators to be applied to `model`, `enum`, `union`, and `scalar` declarations used in expression position. Inline decorators can be applied directly, and augment decorators (`@@`) can target them through a navigation reference (such as `::type`).

```tsp
model Foo {
status: @doc("the current status") enum { active, inactive };
inner: @doc("nested model") model Inner { x: string };
}

@@doc(Foo.status::type, "the current status");
```
13 changes: 13 additions & 0 deletions .chronus/changes/decl-expr-doc-comments-2026-4-18-0-0-3.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,13 @@
---
changeKind: feature
packages:
- "@typespec/compiler"
---

Allow a doc comment to be applied inline to a `model`, `enum`, `union`, or `scalar` declaration expression, just like an inline `@doc` decorator.

```tsp
model Foo {
status: /** the current status */ enum { active, inactive };
}
```
19 changes: 19 additions & 0 deletions .chronus/changes/decl-expr-formatting-2026-4-18-0-0-4.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,19 @@
---
changeKind: feature
packages:
- "@typespec/compiler"
---

Improve formatting of declaration expressions (`model`, `enum`, `union`, and `scalar` used in expression position) that carry doc comments and/or decorators. When the inline form would exceed the print width, the doc comments and decorators are now each placed on their own line and the whole block is indented one level instead of overflowing.

```tsp
model Foo {
status:
@summary("a fairly long summary text here")
@example("some-default-example-value")
enum {
active,
inactive,
};
}
```
15 changes: 15 additions & 0 deletions .chronus/changes/decl-expr-json-schema-inline-2026-4-18-0-0-1.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,15 @@
---
changeKind: feature
packages:
- "@typespec/json-schema"
---

Support `model`, `enum`, `union`, and `scalar` declarations used in expression position. Anonymous declaration expressions are inlined, while named ones are hoisted into their own schema.

```tsp
model Foo {
status: enum { active, inactive }; // inlined
unit: scalar extends string; // inlined
inner: model Inner { x: string }; // hoisted as `Inner.json`
}
```
16 changes: 16 additions & 0 deletions .chronus/changes/decl-expr-openapi-inline-2026-4-18-0-0-1.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,16 @@
---
changeKind: feature
packages:
- "@typespec/openapi"
- "@typespec/openapi3"
---

Support `model`, `enum`, `union`, and `scalar` declarations used in expression position. Anonymous declaration expressions are inlined, while named ones are hoisted into a referenced component.
Comment thread
timotheeguerin marked this conversation as resolved.

```tsp
model Foo {
status: enum { active, inactive }; // inlined
unit: scalar extends string; // inlined
inner: model Inner { x: string }; // hoisted as component `Inner`
}
```
7 changes: 7 additions & 0 deletions .chronus/changes/decl-expr-typekit-enum-2026-4-18-0-0-1.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,7 @@
---
changeKind: feature
packages:
- "@typespec/compiler"
---

`$.enum.create` now produces an enum expression (`expression: true`) when given an empty `name`, mirroring `$.model.create`.
Original file line number Diff line number Diff line change
@@ -0,0 +1,7 @@
---
changeKind: feature
packages:
- "@typespec/versioning"
---

Validate the variants of a keyword-form union expression (`union { ... }`) used in expression position like the variants of a named union, so versioning incompatibilities on decorated variants are reported.
Original file line number Diff line number Diff line change
@@ -0,0 +1,7 @@
---
changeKind: fix
packages:
- "@typespec/graphql"
---

Set the required `expression` field to `false` when creating a replacement scalar so scalars produced by the model mutation engine are valid declaration types.
Original file line number Diff line number Diff line change
@@ -0,0 +1,7 @@
---
changeKind: feature
packages:
- "@typespec/html-program-viewer"
---

Display the new `expression` property on `Model`, `Enum`, and `Scalar` types in the program viewer.
Loading
Loading