Skip to content

Implementation valueof #1745

@timotheeguerin

Description

@timotheeguerin

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

  1. if type is unknown or TemplatedString always pass a TemplatedString even if its a string
  2. if type is string convert to a string if possible or fail
  3. if type is string | TemplatedString error saying to pick one

Now we have the case

  1. 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

CadlTs 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) {}

Metadata

Metadata

Labels

No labels
No labels

Type

No type

Projects

No projects

Relationships

None yet

Development

No branches or pull requests

Issue actions