forked from microsoft/typespec
-
Notifications
You must be signed in to change notification settings - Fork 0
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
Add docs #7
Merged
timotheeguerin
merged 4 commits into
timotheeguerin:feature/object-literals
from
bterlson:object-literals-docs
Apr 18, 2024
Merged
Add docs #7
Changes from 1 commit
Commits
Show all changes
4 commits
Select commit
Hold shift + click to select a range
File filter
Filter by extension
Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,131 @@ | ||
--- | ||
id: values | ||
title: Values | ||
--- | ||
|
||
# Values | ||
|
||
TypeSpec can define values in addition to types. Values are useful in an API description to define default values for types or provide example values. They are also useful when passing data to decorators, and for template parameters that are ultimately passed to decorators. | ||
|
||
There are three kinds of values: objects, arrays, and scalars. These values can be created with object literals, array literals, and scalar literals and initializers. Additionally, values can result from referencing enum members and union variants. | ||
|
||
## Object values | ||
|
||
Object values use the syntax `#{}` and can define any number of properties. For example: | ||
|
||
```typespec | ||
const point = #{ | ||
x: 0, | ||
y: 0 | ||
} | ||
``` | ||
|
||
The object value's properties must refer to other values. It is an error to reference a type. | ||
|
||
```typespec | ||
const example = #{ | ||
prop1: #{ nested: true }; // ok | ||
prop2: { nested: true }; // error: values can't reference a type | ||
prop3: string; // error: values can't reference a type | ||
} | ||
``` | ||
|
||
## Array values | ||
|
||
Array values use the syntax `#[]` and can define any number of items. For example: | ||
|
||
```typespec | ||
const points = #[ | ||
#{ x: 0, y: 0}, | ||
#{ x: 1, y: 1} | ||
] | ||
``` | ||
|
||
As with object values, array values cannot contain types. | ||
|
||
If an array type defines a minimum and maximum size using the `@minValue` and `@maxValue` decorators, the compiler will validate that the array value has the appropriate number of items. For example: | ||
|
||
```typespec | ||
/** Can have at most 3 tags */ | ||
@maxItems(2) | ||
model Tags is Array<string>; | ||
|
||
const exampleTags1: Tags = #["TypeSpec", "JSON"]; // ok | ||
const exampleTags2: Tags = #["TypeSpec", "JSON", "OpenAPI"]; // error | ||
``` | ||
|
||
## Scalar values | ||
|
||
There are two ways to create scalar values: with a literal syntax like `"string value"`, and with a scalar initializer like `utcDateTime.fromISO("2020-12-01T12:00:00Z")`. | ||
|
||
### Scalar literals | ||
|
||
The literal syntax for strings, numerics, booleans and null can evaluate to either a type or a value depending on the surrounding context of the literal. When the literal is in _type context_ (a model property type, operation return type, alias definition, etc.) the literal becomes a literal type. When the literal is in _value context_ (a default value, property of an object value, const definition, etc.), the literal becomes a value. When the literal is in an _ambiguous context_ (e.g. an argument to a template or decorator that can accept either a type or a value) the literal becomes a value. The `typeof` operator can be used to convert the literal to a type in such ambiguous contexts. | ||
|
||
```typespec | ||
extern dec setNumberValue(target: unknown, color: valueof numeric); | ||
extern dec setNumberType(target: unknown, color: numeric); | ||
extern dec setNumberTypeOrValue(target: unknown, color: numeric | (valueof numeric)); | ||
|
||
@setNumberValue(123) // Passes the scalar value `numeric(123)`. | ||
@setNumberType(123) // Passes the numeric literal type 123. | ||
@setNumberTypeOrValue(123) // passes the scalar value `numeric(123)`. | ||
model A {} | ||
``` | ||
|
||
### Scalar initializers | ||
|
||
Scalar initializers create scalar values by calling an initializer with one or more values. Scalar initializers for types extended from `numeric`, `string`, and `boolean` are called by adding parenthesis after the scalar reference: | ||
|
||
```typespec | ||
const n = int8(100); | ||
const s = string("hello"); | ||
``` | ||
|
||
Any scalar can additionally be declared with named initializers that take one or more value parameters. For example, `utcDateTime` provides a `fromISO` initializer that takes an ISO string. Named scalars can be declared like so: | ||
|
||
```typespec | ||
scalar IPv4 extends string { | ||
bterlson marked this conversation as resolved.
Show resolved
Hide resolved
|
||
init fromInt(uint32); | ||
bterlson marked this conversation as resolved.
Show resolved
Hide resolved
|
||
} | ||
|
||
const ip = IPv4.fromInt(2341230); | ||
bterlson marked this conversation as resolved.
Show resolved
Hide resolved
|
||
``` | ||
|
||
## Enum member & union variant references | ||
|
||
References to enum members and union variants can be either types or values and follow the same rules as scalar literals. When an enum member reference is in _type context_, the reference becomes an enum member type. When in _value context_ or _ambiguous context_ the reference becomes the enum member's value. | ||
|
||
```typespec | ||
extern dec setColorValue(target: unknown, color: valueof string); | ||
extern dec setColorMember(target: unknown, color: Reflection.EnumMember); | ||
|
||
enum Color { | ||
red, | ||
green, | ||
blue, | ||
} | ||
|
||
@setColorValue(Color.red) // same as passing the literal "red" | ||
@setColorMember(Color.red) // passes the enum member Color.red | ||
model A {} | ||
``` | ||
|
||
When a union variant reference is in _type context_, the reference becomes the type of the union variant. When in _value context_ or _ambiguous context_ the reference becomes the value of the union variant. It is an error to refer to a union variant whose type is not a literal type. | ||
|
||
```typespec | ||
extern dec setColorValue(target: unknown, color: valueof string); | ||
extern dec setColorType(target: unknown, color: string); | ||
|
||
union Color { | ||
red: "red", | ||
green: "green", | ||
blue: "blue", | ||
other: string, | ||
} | ||
|
||
@setColorValue(Color.red) // passes the scalar value `string("red")` | ||
@setColorValue(Color.other) // error, trying to pass a type as a value. | ||
@setColorType(Color.red) // passes the string literal type `"red"` | ||
model A {} | ||
``` |
Add this suggestion to a batch that can be applied as a single commit.
This suggestion is invalid because no changes were made to the code.
Suggestions cannot be applied while the pull request is closed.
Suggestions cannot be applied while viewing a subset of changes.
Only one suggestion per line can be applied in a batch.
Add this suggestion to a batch that can be applied as a single commit.
Applying suggestions on deleted lines is not supported.
You must change the existing code in this line in order to create a valid suggestion.
Outdated suggestions cannot be applied.
This suggestion has been applied or marked resolved.
Suggestions cannot be applied from pending reviews.
Suggestions cannot be applied on multi-line comments.
Suggestions cannot be applied while the pull request is queued to merge.
Suggestion cannot be applied right now. Please check back later.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
and null