Implementation of design #888
Add a new keyword called valueof that can prefix a type reference to mean that valueof TypeReference should be a value type.
valueof Scalars
Add a new keyword valueof that will let us solve this problem.
Syntax
// Option 1: With parenthese
valueof(<type>)
valueof(string)
// Option 2: Keyword
valueof <type>
valueof string
| Syntax |
Meaning |
Example |
valueof(string) |
A String literal |
"foo" |
valueof(int32) |
A integer literal |
123456 |
valueof(int8) |
A integer literal(Assignable to int8) |
5 |
valueof(boolean) |
A boolean literal |
true |
valueof("foo" | "bar") |
A String literal that match the union |
"foo" |
valueof Record
First part adds a way to patch the gap for literal types. This would do a similar behavior for records.
Those values could be provided with the #{} syntax.
model Role {
id: int32;
name: string;
}
valueof(Role) // would mean the following
// Assignable
alias A1 = #{ id: 1 , name: "read" }
alias A2 = #{ id: 2 , name: "write" }
// Not assignable
alias B1 = #{ id: 1 , name: "read", extra: "plus" } // Extra property
alias B2 = #{ id: int32, name: "read" } // Not a value type
Applies valueof whenever possible recursively to each of the property type
model User {
id: int32;
address: {
city: string
}
}
#{id: 2, address: {city: "Foo"}}
Conversion of value to JS
That the rules we decided with template string proposal
- if type is unknown or TemplatedString always pass a TemplatedString even if its a string
- if type is string convert to a string if possible or fail
- if type is string | TemplatedString error saying to pick one
Now we have the case
- if type is typeof string then we pass a string or fail
This mean we probably don't want 2. to convert to a string anymore. So if you have string as the param type and the passed arg is a
string literal -> keep as it is
string model(or derived) -> keep as it is
template literal-> keep as it is but error if its not serializable to string?
For #3 we probably want to also fail for valueof string | TemplateLiteral
For example this would be the generated payloads
| Cadl | Ts Signature |
dec foo(target, value: string)
|
export function $foo(
context,
target,
value: StringLiteral | TemplateLiteral | Scalar
) {}
|
dec foo(target, value: valueof string)
|
export function $foo(context, target, value: string) {}
|
dec foo(target, value: TemplateLiteral)
|
export function $foo(context, target, value: TemplateLiteral) {}
|
Implementation of design #888
Add a new keyword called
valueofthat can prefix a type reference to mean thatvalueof TypeReferenceshould be a value type.valueof Scalars
Add a new keyword
valueofthat will let us solve this problem.Syntax
valueof(string)"foo"valueof(int32)123456valueof(int8)5valueof(boolean)truevalueof("foo" | "bar")"foo"valueof Record
First part adds a way to patch the gap for literal types. This would do a similar behavior for records.
Those values could be provided with the
#{}syntax.Applies
valueofwhenever possible recursively to each of the property typeConversion of value to JS
That the rules we decided with template string proposal
Now we have the case
This mean we probably don't want 2. to convert to a string anymore. So if you have
stringas the param type and the passed arg is astring literal-> keep as it isstring model(or derived)-> keep as it istemplate literal-> keep as it is but error if its not serializable to string?For #3 we probably want to also fail for valueof string | TemplateLiteral
For example this would be the generated payloads