Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
28 commits
Select commit Hold shift + click to select a range
65fbbd3
Parse valueof
timotheeguerin Apr 17, 2023
566c1f7
Parse valueof
timotheeguerin Apr 17, 2023
0f98a44
Merge branch 'main' of https://github.com/Microsoft/typespec into fea…
timotheeguerin May 1, 2023
987cb50
Basic validation
timotheeguerin May 1, 2023
128711f
Some tests
timotheeguerin May 1, 2023
a9cba02
Fix
timotheeguerin May 1, 2023
a114d0c
Works in template constraints
timotheeguerin May 1, 2023
8f46e60
Fix tests
timotheeguerin May 1, 2023
0840853
change marshalling rules
timotheeguerin May 1, 2023
64843fb
Add grammar and regen docs
timotheeguerin May 2, 2023
f7b9fef
Add colorization tests
timotheeguerin May 2, 2023
ce62ffb
Fix
timotheeguerin May 2, 2023
96a4da6
Merge branch 'main' into feature/valueof
timotheeguerin May 2, 2023
c8b40ef
Merge branch 'feature/valueof' of https://github.com/timotheeguerin/t…
timotheeguerin May 2, 2023
8c69389
Add backcompat from template constraint
timotheeguerin May 2, 2023
1faad39
Merge with main
timotheeguerin May 24, 2023
db49ae4
Add docs
timotheeguerin May 24, 2023
2bfc68c
Merge branch 'main' into feature/valueof
timotheeguerin May 24, 2023
8d9054c
Changelog
timotheeguerin May 24, 2023
6194e04
Format
timotheeguerin May 24, 2023
6be312a
Fix lint
timotheeguerin May 24, 2023
389f5ed
remove console.log
timotheeguerin May 24, 2023
a93affa
Fix petstore decorators
timotheeguerin May 24, 2023
a7cbd1b
Merge with main
timotheeguerin Jun 1, 2023
2f64651
fix
timotheeguerin Jun 1, 2023
08db01a
regen docs
timotheeguerin Jun 1, 2023
49669b3
MErge with main
timotheeguerin Jun 2, 2023
c7743b4
Merge branch 'main' into feature/valueof
timotheeguerin Jun 2, 2023
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,20 @@
{
"changes": [
{
"packageName": "@typespec/compiler",
"comment": "Added new keyword `valueof` designed to request for a value type in a decorator parameter.",
"type": "none"
},
{
"packageName": "@typespec/compiler",
"comment": "**BREAKING** Decorator API will not be marshalling values unless the parameter type is using `valueof`. `extern dec foo(target, value: string)` should be changed to `extern dec foo(target, value: valueof string)`.",
"type": "none"
},
{
"packageName": "@typespec/compiler",
"comment": "**DEPRECATION** To make transition to valueof smoother if using a template parameter inside a decorator that is now using valueof the existing parmater constraint will still be compatible but emit a warning.",
"type": "none"
}
],
"packageName": "@typespec/compiler"
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,10 @@
{
"changes": [
{
"packageName": "@typespec/http",
"comment": "Update decorators to use `valueof`",
"type": "none"
}
],
"packageName": "@typespec/http"
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,10 @@
{
"changes": [
{
"packageName": "@typespec/openapi",
"comment": "Update decorators to use `valueof`",
"type": "none"
}
],
"packageName": "@typespec/openapi"
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,10 @@
{
"changes": [
{
"packageName": "@typespec/protobuf",
"comment": "Update decorators to use `valueof`",
"type": "minor"
}
],
"packageName": "@typespec/protobuf"
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,10 @@
{
"changes": [
{
"packageName": "@typespec/rest",
"comment": "Update decorators to use `valueof`",
"type": "none"
}
],
"packageName": "@typespec/rest"
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,10 @@
{
"changes": [
{
"packageName": "@typespec/versioning",
"comment": "Update decorators to use `valueof`",
"type": "none"
}
],
"packageName": "@typespec/versioning"
}
40 changes: 31 additions & 9 deletions docs/extending-typespec/create-decorators.md
Original file line number Diff line number Diff line change
Expand Up @@ -40,15 +40,37 @@ extern dec track(target: Model | Enum);
A decorator parameter can be marked optional using `?`

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

### Rest parameters

A decorator's last parameter can be prefixed with `...` to collect all the remaining arguments. The type of that parameter must be an `array expression`

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

## Ask for a value type

It is common that decorators parameter will expect a value(e.g. a string or a number). However just using `: string` as the type will also allow a user of the decorator to pass `string` itself or a custom scalar extending string as well as union of strings.
Instead the decorator can use `valueof <T>` to specify that it is expecting a value of that kind.

| Example | Description |
| ----------------- | ---------------- |
| `valueof string` | Expect a string |
| `valueof float64` | Expect a float |
| `valueof int32` | Expect a number |
| `valueof boolean` | Expect a boolean |

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

// bad
@tag(string)

// good
@tag("This is the tag name")
```

## Implement the decorator in JS
Expand All @@ -63,7 +85,7 @@ Decorators can be implemented in JavaScript by prefixing the function name with
// model.ts
import type { DecoratorContext, Type } from "@typespec/compiler";

export function $logType(context: DecoratorContext, target: Type, name: string) {
export function $logType(context: DecoratorContext, target: Type, name: valueof string) {
console.log(name + ": " + targetType.kind);
}
```
Expand Down Expand Up @@ -92,13 +114,13 @@ model Dog {

### Decorator parameter marshalling

For certain TypeSpec types(Literal types) the decorator do not receive the actual type but a marshalled value. This is to simplify the most common cases.
For certain TypeSpec types(Literal types) the decorator do not receive the actual type but a marshalled value if the decorator parmaeter type is a `valueof`. This is to simplify the most common cases.

| TypeSpec Type | Marshalled value in JS |
| ---------------- | ---------------------- |
| `StringLiteral` | `string` |
| `NumericLiteral` | `number` |
| `BooleanLiteral` | `boolean` |
| TypeSpec Type | Marshalled value in JS |
| ----------------- | ---------------------- |
| `valueof string` | `string` |
| `valueof numeric` | `number` |
| `valueof boolean` | `boolean` |

for all the other types they are not transformed.

Expand Down
Loading