Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Value world, object, tuple literals, const #3022

Merged
merged 210 commits into from
May 8, 2024
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
210 commits
Select commit Hold shift + click to select a range
49f51ca
Initial implementation of Object
timotheeguerin Mar 14, 2024
a517a06
Add support for tuple literals
timotheeguerin Mar 14, 2024
9a6d548
fix formatter
timotheeguerin Mar 14, 2024
97effa8
Simplify
timotheeguerin Mar 14, 2024
6a263cf
Fixes
timotheeguerin Mar 14, 2024
320797c
Add tests for basic checking
timotheeguerin Mar 15, 2024
6948455
Tm language and spec
timotheeguerin Mar 15, 2024
3560171
Add valueof assignment
timotheeguerin Mar 15, 2024
898beb6
Marshall types
timotheeguerin Mar 15, 2024
91b4d45
project
timotheeguerin Mar 15, 2024
12ed54d
Merge branch 'main' into feature/object-literals
timotheeguerin Mar 15, 2024
8376eee
Handle defaults
timotheeguerin Mar 15, 2024
e23685f
Fix
timotheeguerin Mar 15, 2024
80518d2
Create feature-object-literals-2024-2-15-18-36-3.md
timotheeguerin Mar 15, 2024
29b49f8
Create feature-object-literals-32024-2-15-18-36-3.md
timotheeguerin Mar 15, 2024
a5283b2
.
timotheeguerin Mar 15, 2024
ce94cd8
Add test to make sure value not allowed in certain usages
timotheeguerin Mar 15, 2024
8f32964
Fix
timotheeguerin Mar 15, 2024
a1cc33f
.
timotheeguerin Mar 15, 2024
759d09c
Fix openapi3 emitter
timotheeguerin Mar 15, 2024
9611adc
Create feature-object-literals-2024-2-15-21-56-46.md
timotheeguerin Mar 15, 2024
7cb98d5
Add quickfix
timotheeguerin Mar 15, 2024
89a7811
Fix filename
timotheeguerin Mar 15, 2024
377f8b6
Add codefix to convert model expression to object literal
timotheeguerin Mar 15, 2024
f387e1e
Fix
timotheeguerin Mar 15, 2024
7bec3ab
.
timotheeguerin Mar 16, 2024
1738240
Unify Values and allow enum member as values
timotheeguerin Mar 16, 2024
deced7a
.
timotheeguerin Mar 16, 2024
8129fe4
.
timotheeguerin Mar 16, 2024
fd87dc3
progress
timotheeguerin Mar 16, 2024
6a326cd
Merge branch 'main' into feature/object-literals
timotheeguerin Mar 18, 2024
c5004e3
fix
timotheeguerin Mar 18, 2024
d131045
Add new ParamConstraintUnion
timotheeguerin Mar 18, 2024
fd019aa
.
timotheeguerin Mar 18, 2024
df8dcaf
Fix
timotheeguerin Mar 18, 2024
b402ce7
Split
timotheeguerin Mar 18, 2024
34adfbe
Create feature-object-literals-2024-2-18-22-23-26.md
timotheeguerin Mar 18, 2024
14efb01
fix
timotheeguerin Mar 18, 2024
bc24b0e
Merge branch 'feature/object-literals' of https://github.com/timothee…
timotheeguerin Mar 18, 2024
b6979cf
Merge branch 'main' into feature/object-literals
timotheeguerin Mar 19, 2024
d253264
Test
timotheeguerin Mar 19, 2024
f7eb99a
Fix up issues
timotheeguerin Mar 19, 2024
b4f84d7
Get tuple
timotheeguerin Mar 19, 2024
07f461e
Additional properties
timotheeguerin Mar 19, 2024
1d9bd2b
.
timotheeguerin Mar 20, 2024
adf8efc
Merge branch 'main' of https://github.com/Microsoft/typespec into fea…
timotheeguerin Apr 4, 2024
856699c
Add support for const in parser
timotheeguerin Apr 4, 2024
262f670
Merge branch 'main' into feature/object-literals
timotheeguerin Apr 9, 2024
6dead0d
Introduce Value entities
timotheeguerin Apr 10, 2024
3da5cff
call expression
timotheeguerin Apr 10, 2024
0126ffa
add tests for call expression parsing
timotheeguerin Apr 10, 2024
134d3b6
Add scalar constructors parsing and formatter
timotheeguerin Apr 10, 2024
dfb2874
Add colorization for scalar consutructors
timotheeguerin Apr 10, 2024
10e69f9
update grammar
timotheeguerin Apr 10, 2024
4b29c93
Delete .chronus/changes/feature-object-literals-2024-2-15-21-56-46.md
timotheeguerin Apr 10, 2024
cf59227
Fix
timotheeguerin Apr 10, 2024
225fb07
Merge branch 'feature/object-literals' of https://github.com/timothee…
timotheeguerin Apr 10, 2024
63f46cb
no decorator on scalar members
timotheeguerin Apr 10, 2024
258f1f4
Merge branch 'main' into feature/object-literals
timotheeguerin Apr 10, 2024
26cda8a
named constructor checking
timotheeguerin Apr 11, 2024
e2a4787
Compare using Numeric
timotheeguerin Apr 11, 2024
08fb196
min
timotheeguerin Apr 11, 2024
56bbb6e
Progress with tests
timotheeguerin Apr 11, 2024
95c96af
Merge branch 'main' of https://github.com/Microsoft/typespec into fea…
timotheeguerin Apr 11, 2024
218e454
Tests
timotheeguerin Apr 11, 2024
0503b61
Fix up tests
timotheeguerin Apr 11, 2024
2bc3ee4
infer type from const value
timotheeguerin Apr 11, 2024
9f2898c
add test for ambiguous numeric
timotheeguerin Apr 11, 2024
a964e9d
cache constant values
timotheeguerin Apr 11, 2024
5701b7b
Add string and boolean values tests
timotheeguerin Apr 11, 2024
be288fd
Scalar values
timotheeguerin Apr 11, 2024
bb357b7
Better way to resolve values vs types
timotheeguerin Apr 11, 2024
de6f139
Progress
timotheeguerin Apr 11, 2024
0455316
Type
timotheeguerin Apr 11, 2024
7953580
more tests
timotheeguerin Apr 12, 2024
4662df3
Js marshaller conditional Numeric
timotheeguerin Apr 12, 2024
1117fba
More marshalling tests
timotheeguerin Apr 12, 2024
f68a677
nit fixes
timotheeguerin Apr 12, 2024
e785441
special projection marshal
timotheeguerin Apr 12, 2024
16d6ef5
Merge branch 'main' of https://github.com/Microsoft/typespec into fea…
timotheeguerin Apr 12, 2024
1032772
small test fix
timotheeguerin Apr 12, 2024
aef40ad
Convert numeric decorators
timotheeguerin Apr 12, 2024
bde6748
Show contextual errors for arguments
timotheeguerin Apr 12, 2024
6a30fd7
Fix template parameters
timotheeguerin Apr 12, 2024
a759d23
.
timotheeguerin Apr 12, 2024
a6aeb71
progress
timotheeguerin Apr 12, 2024
edd8ad0
progress
timotheeguerin Apr 12, 2024
5c0e117
Merge branch 'main' of https://github.com/Microsoft/typespec into fea…
timotheeguerin Apr 12, 2024
a57ff40
Improve diag messages and fix tests
timotheeguerin Apr 12, 2024
1a4f18d
Validate excess properties for value declarations
timotheeguerin Apr 12, 2024
deed566
cleanup
timotheeguerin Apr 12, 2024
603dd2c
cleanup and fix last tests
timotheeguerin Apr 12, 2024
9804e8d
Fix json schema
timotheeguerin Apr 12, 2024
a583297
more fixes
timotheeguerin Apr 12, 2024
68e87ca
Fix up build
timotheeguerin Apr 12, 2024
6feee8e
regen some docs
timotheeguerin Apr 12, 2024
ccdfeb6
some fixes
timotheeguerin Apr 12, 2024
b814cbd
Support union variants
timotheeguerin Apr 12, 2024
7c04ff6
fix protobuf tests
timotheeguerin Apr 12, 2024
3059031
http and rest test fix
timotheeguerin Apr 12, 2024
560330c
actually cast tuple as value
timotheeguerin Apr 12, 2024
f53a83a
Better conversion of legacy model and tuple to values
timotheeguerin Apr 13, 2024
82601cb
default can also cast tuple
timotheeguerin Apr 13, 2024
56deca2
format
timotheeguerin Apr 13, 2024
5892af7
Merge branch 'main' of https://github.com/Microsoft/typespec into fea…
timotheeguerin Apr 13, 2024
b6f4f61
merge with main
timotheeguerin Apr 13, 2024
bbf9022
remove unnecessary marshalling
timotheeguerin Apr 13, 2024
609481e
Merge branch 'main' into feature/object-literals
timotheeguerin Apr 15, 2024
64c371b
Better string template handling
timotheeguerin Apr 15, 2024
008ba34
.
timotheeguerin Apr 15, 2024
dfe0bf2
missing return
timotheeguerin Apr 16, 2024
1884559
string value test
timotheeguerin Apr 16, 2024
f1ae081
Opt-in new marshalling
timotheeguerin Apr 16, 2024
b5a80a1
fix null test
timotheeguerin Apr 16, 2024
3b52b6e
add defaultValue tests
timotheeguerin Apr 16, 2024
0d1d605
Add validation for min, max value and length
timotheeguerin Apr 16, 2024
327e4fb
rename and fix
timotheeguerin Apr 16, 2024
483f27c
Create feature-object-literals-2024-3-16-17-54-23.md
timotheeguerin Apr 16, 2024
55a1488
fix lint
timotheeguerin Apr 16, 2024
d24d622
Merge branch 'feature/object-literals' of https://github.com/timothee…
timotheeguerin Apr 16, 2024
da8e037
Add string template tests
timotheeguerin Apr 16, 2024
212533c
Add valueof casting tests
timotheeguerin Apr 16, 2024
894d08c
Changelog
timotheeguerin Apr 16, 2024
f5dadec
Merge branch 'main' into feature/object-literals
timotheeguerin Apr 16, 2024
265634e
Update .chronus/changes/feature-object-literals-32024-2-15-18-36-3.md
timotheeguerin Apr 16, 2024
184175a
Merge branch 'main' into feature/object-literals
timotheeguerin Apr 18, 2024
ac79e22
add notes
bterlson Apr 18, 2024
dd89960
Update docs/language-basics/values.md
bterlson Apr 18, 2024
c4f0c7f
Update docs/language-basics/values.md
bterlson Apr 18, 2024
c5a2564
Update docs/language-basics/values.md
bterlson Apr 18, 2024
b751e6e
Merge pull request #7 from bterlson/object-literals-docs
timotheeguerin Apr 18, 2024
fadfa7a
Merge branch 'main' of https://github.com/Microsoft/typespec into fea…
timotheeguerin Apr 18, 2024
1dd06c2
abc
timotheeguerin Apr 18, 2024
fd01267
Validate min/max items for tuples to array
timotheeguerin Apr 19, 2024
8a1f95c
fix
timotheeguerin Apr 19, 2024
8438d6c
remove outdated doc
timotheeguerin Apr 19, 2024
25b6b9e
Add parse support for typeof
timotheeguerin Apr 19, 2024
7afcec1
Limit typeof syntax and organize valueof
timotheeguerin Apr 20, 2024
53c8a74
Rename
timotheeguerin Apr 20, 2024
d4d778b
Structured mixed constraint
timotheeguerin Apr 20, 2024
02de1e7
Mixed function parameter
timotheeguerin Apr 20, 2024
e8e4024
fix tspd
timotheeguerin Apr 20, 2024
67f2eaf
fix
timotheeguerin Apr 20, 2024
fc2618c
abc
timotheeguerin Apr 20, 2024
bae371d
simplify
timotheeguerin Apr 20, 2024
1d2f418
Don't need valueconstraint anymore
timotheeguerin Apr 20, 2024
2678b38
missing
timotheeguerin Apr 20, 2024
efb29df
better way of dealing with templates
timotheeguerin Apr 20, 2024
1b5ea8e
string template that serialize to string is assignable to the string …
timotheeguerin Apr 20, 2024
6e5fb91
Move mixedconstraint to not be a type
timotheeguerin Apr 21, 2024
5b5f3bc
Fix doc generation
timotheeguerin Apr 21, 2024
6ad1cd4
Fix docs
timotheeguerin Apr 22, 2024
3fa5a92
format
timotheeguerin Apr 22, 2024
73e1c6c
Treat templates as syntax template (#8)
timotheeguerin Apr 25, 2024
7d8441d
Add validation of usage of template with valueof vs not
timotheeguerin Apr 25, 2024
096e2e2
Fix some assignment issues
timotheeguerin Apr 25, 2024
c84051d
Merge branch 'main' of https://github.com/Microsoft/typespec into fea…
timotheeguerin Apr 25, 2024
ad161a1
fix
timotheeguerin Apr 25, 2024
ee65807
Fix test
timotheeguerin Apr 25, 2024
6c1b42c
fix up tests
timotheeguerin Apr 25, 2024
5575e5f
Fix up deprecations
timotheeguerin Apr 25, 2024
86e9f6c
fix
timotheeguerin Apr 25, 2024
c038969
Fix
timotheeguerin Apr 25, 2024
4fc4900
Fix declare const in a namespace
timotheeguerin Apr 25, 2024
206fb0f
Push
timotheeguerin Apr 25, 2024
88c848d
Fix ide reporting diagnostics on hover
timotheeguerin Apr 25, 2024
80f5021
update spec
timotheeguerin Apr 26, 2024
2d729a2
Fix
timotheeguerin Apr 26, 2024
745d8b9
fix invalid
timotheeguerin Apr 26, 2024
533e4ba
Update docs/language-basics/values.md
timotheeguerin Apr 29, 2024
6c55bdf
Merge branch 'main' of https://github.com/Microsoft/typespec into fea…
timotheeguerin Apr 30, 2024
03ac2d4
Merge branch 'feature/object-literals' of https://github.com/timothee…
timotheeguerin Apr 30, 2024
56e88cb
Add const hovering
timotheeguerin May 2, 2024
68bdfef
add hover tests
timotheeguerin May 2, 2024
64b31c2
String literal assignable to string template
timotheeguerin May 2, 2024
eed204b
add validation for interpolating invalid template parmater
timotheeguerin May 2, 2024
da4ab8d
More value docs (#9)
bterlson May 4, 2024
e0d7bf5
More
timotheeguerin May 6, 2024
e8c4b7c
Fix bug
timotheeguerin May 6, 2024
520d681
Rename
timotheeguerin May 6, 2024
f4de434
Cleanup
timotheeguerin May 6, 2024
c300350
rename tuple literal to array literal
timotheeguerin May 6, 2024
4050eda
Merge branch 'main' into feature/object-literals
timotheeguerin May 6, 2024
f5582f3
Todo
timotheeguerin May 6, 2024
a110a5d
Apply suggestions from code review
timotheeguerin May 6, 2024
540dd96
Rename object literals -> object values where it make sense
timotheeguerin May 6, 2024
674fe27
Merge branch 'feature/object-literals' of https://github.com/timothee…
timotheeguerin May 6, 2024
4086daf
Migrate array literal to value nameing
timotheeguerin May 6, 2024
ef3b656
Update .chronus/changes/feature-object-literals-2024-3-16-17-54-23.md
timotheeguerin May 6, 2024
158e991
Update .chronus/changes/feature-object-literals-2024-3-16-10-38-3.md
timotheeguerin May 6, 2024
ed754c7
Update .chronus/changes/feature-object-literals-2024-3-16-10-38-3.md
timotheeguerin May 6, 2024
d1a0052
Update packages/compiler/lib/intrinsics.tsp
timotheeguerin May 6, 2024
66dc669
Update packages/compiler/lib/intrinsics.tsp
timotheeguerin May 6, 2024
741e03d
Some CR fixes
timotheeguerin May 6, 2024
fbab31e
Update packages/compiler/src/core/messages.ts
timotheeguerin May 6, 2024
4d53ef4
More CR comments
timotheeguerin May 6, 2024
1e01b42
Merge branch 'feature/object-literals' of https://github.com/timothee…
timotheeguerin May 6, 2024
9c1bca5
Merge branch 'main' of https://github.com/Microsoft/typespec into fea…
timotheeguerin May 6, 2024
94ce40a
ADd more scalar constructor and docs
timotheeguerin May 7, 2024
9a02980
Add tests
timotheeguerin May 7, 2024
5eca49f
Fix marshalling of enum members
timotheeguerin May 7, 2024
1b59484
Fix another issue with template default
timotheeguerin May 7, 2024
6030a9c
Update packages/compiler/src/core/checker.ts
timotheeguerin May 7, 2024
feecb80
Update packages/compiler/src/core/checker.ts
timotheeguerin May 7, 2024
83f613d
Add new `entityKind` property to
timotheeguerin May 8, 2024
3031a77
remove todo
timotheeguerin May 8, 2024
2d068c7
Better errors when trying to get a value of model/tuple
timotheeguerin May 8, 2024
98e9d05
Merge branch 'main' into feature/object-literals
timotheeguerin May 8, 2024
87bdb56
Fix tm grammar for scalar body
timotheeguerin May 8, 2024
2425dc6
Fix
timotheeguerin May 8, 2024
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
17 changes: 17 additions & 0 deletions .chronus/changes/feature-object-literals-2024-2-15-18-36-3-1.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,17 @@
---
# Change versionKind to one of: internal, fix, dependencies, feature, deprecation, breaking
changeKind: deprecation
packages:
- "@typespec/compiler"
---

Using a tuple type as a value is deprecated. Tuple types in contexts where values are expected must be updated to be array values instead. A codefix is provided to automatically convert tuple types into array values.

```tsp
model Test {
// Deprecated
values: string[] = ["a", "b", "c"];

// Correct
values: string[] = #["a", "b", "c"];
```
17 changes: 17 additions & 0 deletions .chronus/changes/feature-object-literals-2024-2-15-18-36-3-2.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,17 @@
---
# Change versionKind to one of: internal, fix, dependencies, feature, deprecation, breaking
changeKind: deprecation
packages:
- "@typespec/compiler"
---

Using a model type as a value is deprecated. Model types in contexts where values are expected must be updated to be object values instead. A codefix is provided to automatically convert model types into object values.

```tsp
model Test {
// Deprecated
user: {name: string} = {name: "System"};

// Correct
user: {name: string} = #{name: "System"};
```
30 changes: 30 additions & 0 deletions .chronus/changes/feature-object-literals-2024-2-15-18-36-3.md
timotheeguerin marked this conversation as resolved.
Show resolved Hide resolved
Original file line number Diff line number Diff line change
@@ -0,0 +1,30 @@
---
# Change versionKind to one of: internal, fix, dependencies, feature, deprecation, breaking
changeKind: feature
packages:
- "@typespec/compiler"
---

Add syntax for declaring values. [See docs](https://typespec.io/docs/language-basics/values).

Object and array values
```tsp
@dummy(#{
name: "John",
age: 48,
address: #{ city: "London" }
aliases: #["Bob", "Frank"]
})
```

Scalar constructors

```tsp
scalar utcDateTime {
init fromISO(value: string);
}

model DateRange {
minDate: utcDateTime = utcDateTime.fromISO("2024-02-15T18:36:03Z");
}
```
10 changes: 10 additions & 0 deletions .chronus/changes/feature-object-literals-2024-2-18-22-23-26.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,10 @@
---
# Change versionKind to one of: internal, fix, dependencies, feature, deprecation, breaking
changeKind: fix
packages:
- "@typespec/json-schema"
- "@typespec/protobuf"
- "@typespec/versioning"
---

Update to support new value types
23 changes: 23 additions & 0 deletions .chronus/changes/feature-object-literals-2024-3-16-10-38-3.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,23 @@
---
changeKind: deprecation
packages:
- "@typespec/compiler"
---

Decorator API: Legacy marshalling logic

With the introduction of values, the decorator marshalling behavior has changed in some cases. This behavior is opt-in by setting the `valueMarshalling` package flag to `"new"`, but will be the default behavior in future versions. It is strongly recommended to adopt this new behavior as soon as possible.


Example:
```tsp
extern dec multipleOf(target: numeric | Reflection.ModelProperty, value: valueof numeric);
```
Will now emit a deprecated warning because `value` is of type `valueof string` which would marshall to `Numeric` under the new logic but as `number` previously.

To opt-in you can add the following to your library js/ts files.
```ts
export const $flags = definePackageFlags({
decoratorArgMarshalling: "new",
});
```
Original file line number Diff line number Diff line change
@@ -0,0 +1,7 @@
---
changeKind: feature
packages:
- "@typespec/openapi3"
---

Add support for new object and array values as default values (e.g. `decimals: decimal[] = #[123, 456.7];`)
Original file line number Diff line number Diff line change
@@ -0,0 +1,7 @@
---
changeKind: fix
packages:
- "@typespec/rest"
---

Update types to support new values in TypeSpec
Original file line number Diff line number Diff line change
@@ -0,0 +1,8 @@
---
# Change versionKind to one of: internal, fix, dependencies, feature, deprecation, breaking
changeKind: feature
packages:
- "@typespec/html-program-viewer"
---

Add support for values
Original file line number Diff line number Diff line change
@@ -0,0 +1,9 @@
---
# Change versionKind to one of: internal, fix, dependencies, feature, deprecation, breaking
changeKind: fix
packages:
- "@typespec/http"
---

Update Flow Template to make use of the new array values

20 changes: 16 additions & 4 deletions docs/extending-typespec/basics.md
Original file line number Diff line number Diff line change
Expand Up @@ -106,7 +106,7 @@ Open `./src/lib.ts` and create your library definition that registers your libra
If `$lib` is not accessible from your library package (for example, `import {$lib} from "my-library";`), some features such as linting and emitter option validation will not be available.
:::

Here's an example:
For example:

```typescript
import { createTypeSpecLibrary } from "@typespec/compiler";
Expand All @@ -122,7 +122,19 @@ export const { reportDiagnostic, createDiagnostic } = $lib;

Diagnostics are used for linters and decorators, which are covered in subsequent topics.

### f. Create `index.ts`
### f. Set package flags

You can optionally set any package flags by exporting a `$flags` const that is initialized with the `definePackageFlags`. Like `$lib`, this value must be exported from your package.

It is strongly recommended to set `valueMarshalling` to `"new"` as this will be the default behavior in future TypeSpec versions.

```typescript
export const $flags = definePackageFlags({
valueMarshalling: "new",
});
```

### g. Create `index.ts`

Open `./src/index.ts` and import your library definition:

Expand All @@ -131,7 +143,7 @@ Open `./src/index.ts` and import your library definition:
export { $lib } from "./lib.js";
```

### g. Build TypeScript
### h. Build TypeScript

TypeSpec can only import JavaScript files, so any changes made to TypeScript sources need to be compiled before they are visible to TypeSpec. To do this, run `npx tsc -p .` in your library's root directory. If you want to re-run the TypeScript compiler whenever files are changed, you can run `npx tsc -p . --watch`.

Expand All @@ -148,7 +160,7 @@ Alternatively, you can add these as scripts in your `package.json` to make them

You can then run `npm run build` or `npm run watch` to build or watch your library.

### h. Add your main TypeSpec file
### i. Add your main TypeSpec file

Open `./lib/main.tsp` and import your JS entrypoint. This ensures that when TypeSpec imports your library, the code to define the library is run. When we add decorators in later topics, this import will ensure those get exposed as well.

Expand Down
70 changes: 38 additions & 32 deletions docs/extending-typespec/create-decorators.md
Original file line number Diff line number Diff line change
Expand Up @@ -35,44 +35,41 @@ using TypeSpec.Reflection;
extern dec track(target: Model | Enum);
```

### Optional parameters
## Optional parameters

You can mark a decorator parameter as optional using `?`.

```typespec
extern dec track(target: Model | Enum, name?: valueof string);
```

### Rest parameters
## Rest parameters

You can prefix the last parameter of a decorator with `...` to collect all the remaining arguments. The type of this parameter must be an `array expression`.

```typespec
extern dec track(target: Model | Enum, ...names: valueof string[]);
```

## Requesting a value type
## Value parameters

It's common for decorator parameters to expect a value (e.g., a string or a number). However, using `: string` as the type would also allow a user of the decorator to pass `string` itself or a custom scalar extending string, as well as a union of strings. Instead, the decorator can use `valueof <T>` to specify that it expects a value of that kind.

| Example | Description |
| ----------------- | ----------------- |
| `valueof string` | Expects a string |
| `valueof float64` | Expects a float |
| `valueof int32` | Expects a number |
| `valueof boolean` | Expects a boolean |
A decorator parameter can receive [values](../language-basics/values.md) by using the `valueof` operator. For example the parameter `valueof string` expects a string value. Values are provided to the decorator implementation according the [decorator parameter marshalling](#decorator-parameter-marshalling) rules.

```tsp
extern dec tag(target: unknown, value: valueof string);

// bad
// error: string is not a value
@tag(string)

// good
@tag("This is the tag name")
// ok, a string literal can be a value
@tag("widgets")

// ok, passing a value from a const
const tagName: string = "widgets";
@tag(tagName)
```

## Implement the decorator in JavaScript
## JavaScript decorator implementation

Decorators can be implemented in JavaScript by prefixing the function name with `$`. A decorator function must have the following parameters:

Expand All @@ -89,7 +86,7 @@ export function $logType(context: DecoratorContext, target: Type, name: valueof
}
```

Or in pure JavaScript:
Or in JavaScript:

```ts
// model.js
Expand All @@ -113,26 +110,35 @@ model Dog {

### Decorator parameter marshalling

For certain TypeSpec types (Literal types), the decorator does not receive the actual type but a marshalled value if the decorator parameter type is a `valueof`. This simplifies the most common cases.
When decorators are passed types, the type is passed as-is. When a decorator is passed a TypeSpec value, the decorator receives a JavaScript value with a type that is appropriate for representing that value.

| TypeSpec Type | Marshalled value in JS |
| ----------------- | ---------------------- |
| `valueof string` | `string` |
| `valueof numeric` | `number` |
| `valueof boolean` | `boolean` |
:::note
This behavior depends on the value of the `valueMarshalling` [package flag](../extending-typespec/basics.md#f-set-package-flags). This section describes the behavior when `valueMarshalling` is set to `"new"`. In a future release this will become the default value marshalling so it is strongly recommended to set this flag. But for now, the default value marshalling is `"legacy"` which is described in the next section. In a future release the `valueMarshalling` flag will need to be set to `"legacy"` to keep the previous marshalling behavior, but the flag will eventually be removed entirely.
:::

For all other types, they are not transformed.
| TypeSpec value type | Marshalled type in JS |
| ------------------- | --------------------------------- |
| `string` | `string` |
| `boolean` | `boolean` |
| `numeric` | `Numeric` or `number` (see below) |
| `null` | `null` |
| enum member | `EnumMemberValue` |

Example:
When marshalling numeric values, either the `Numeric` wrapper type is used, or a `number` is passed directly, depending on whether the value can be represented as a JavaScript number without precision loss. In particular, the types `numeric`, `integer`, `decimal`, `float`, `int64`, `uint64`, and `decimal128` are marshalled as a `Numeric` type. All other numeric types are marshalled as `number`.

```ts
export function $tag(
context: DecoratorContext,
target: Type,
stringArg: string, // Here instead of receiving a `StringLiteral`, the string value is being sent.
modelArg: Model // Model has no special handling so we receive the Model type
) {}
```
When marshalling custom scalar subtypes, the marshalling behavior of the known supertype is used. For example, a `scalar customScalar extends numeric` will marshal as a `Numeric`, regardless of any value constraints that might be present.

#### Legacy value marshalling

With legacy value marshalling, TypeSpec strings, numbers, and booleans values are always marshalled as JS values. All other values are marshalled as their corresponding type. For example, `null` is marshalled as `NullType`.

| TypeSpec Value Type | Marshalled value in JS |
| ------------------- | ---------------------- |
| `string` | `string` |
| `numeric` | `number` |
| `boolean` | `boolean` |

Note that with legacy marshalling, because JavaScript numbers have limited range and precision, it is possible to define values in TypeSpec that cannot be accurately represented in JavaScript.

#### String templates and marshalling

Expand Down
2 changes: 1 addition & 1 deletion docs/language-basics/decorators.md
Original file line number Diff line number Diff line change
Expand Up @@ -61,4 +61,4 @@ model Dog {

## Creating decorators

_For more information on creating decorators, see the [Creating Decorators Documentation](../extending-typespec/create-decorators.md)._
For more information on creating decorators, see [Creating Decorators](../extending-typespec/create-decorators.md).
16 changes: 15 additions & 1 deletion docs/language-basics/scalars.md
Original file line number Diff line number Diff line change
Expand Up @@ -22,9 +22,23 @@ scalar Password extends string;

## Scalars with template parameters

Scalars can also support template parameters. However, it's important to note that these templates are primarily used for decorators.
Scalars can also support template parameters. These template parameters are primarily used for decorators.

```typespec
@doc(Type)
scalar Unreal<Type extends string>;
```

## Scalar initializers

Scalars can be declared with an initializer for creating specific scalar values based on other values. For example:

```typespec
scalar ipv4 extends string {
init fromInt(value: uint32);
}

const homeIp = ipv4.fromInt(2130706433);
```

Initializers do not have any runtime code associated with them. Instead, they merely record the scalar initializer invoked along with the arguments passed so that emitters can construct the proper value when needed.
40 changes: 40 additions & 0 deletions docs/language-basics/templates.md
Original file line number Diff line number Diff line change
Expand Up @@ -108,3 +108,43 @@ alias Example3 = Test<
Since template arguments can be specified by name, the names of template parameters are part of the template's public API. **Renaming a template parameter may break existing specifications that use the template.**

**Note**: Template arguments are evaluated in the order the parameters are defined in the template _definition_, not the order in which they are written in the template _instance_. While this is usually inconsequential, it may be important in some cases where evaluating a template argument may trigger decorators with side effects.

## Templates with values

Templates can be declared to accept values using a `valueof` constraint. This is useful for providing default values and parameters for decorators that take values.

```typespec
alias TakesValue<StringType extends string, StringValue extends valueof string> = {
@doc(StringValue)
property: StringType;
};

alias M1 = TakesValue<"a", "b">;
```

When a passing a literal or an enum or union member reference directly as a template parameter that accepts either a type or a value, we pass the value. In particular, `StringTypeOrValue` is a value with the string literal type `"a"`.

```typespec
alias TakesTypeOrValue<StringTypeOrValue extends string | (valueof string)> = {
@customDecorator(StringOrValue)
property: string;
};

alias M1 = TakesValue<"a">;
```

The [`typeof` operator](./values.md#the-typeof-operator) can be used to get the declared type of a value if needed.

### Template parameter value types

When a template is instantiated with a value, the type of the value and the result of the `typeof` operator is determined based on the argument rather than the template parameter constraint. This follows the same rules as [const declaration type inference](./values.md#const-declarations). In particular, inside the template `TakesValue`, the type of `StringValue` is the string literal type `"b"`. If we passed a `const` instead, the type of the value would be the const's type. In the following example, the type of `property` in `M1` is `"a" | "b"`.

```typespec
alias TakesValue<StringValue extends valueof string> = {
@doc(StringValue)
property: typeof StringValue;
};

const str: "a" | "b" = "a";
alias M1 = TakesValue<str>;
```
Loading
Loading