Azure / bicep

Bicep is a declarative language for describing and deploying Azure resources
MIT License
3.21k stars 745 forks source link

Add option to create user defined types from static data #14715

Open tehho opened 1 month ago

tehho commented 1 month ago

Is your feature request related to a problem? Please describe. Would be nice to have the option to add types from static data in bicep. Main benefit is that you get intelisence on calling suggestedRoleId() that is dynamically updated.

// does not scale
@export()
type RoleName =
  | 'Contributor'
  | 'Owner'
  | 'Reader'
  | 'Private DNS Zone Contributor'
  | 'Network Contributor'
  | 'Log Analytics Reader'
  | 'Log Analytics Contributor'

@export()
func lookupRoleId(name RoleName) string => loadJsonContent('roles.json')[?name] ?? null

Describe the solution you'd like

// do scale
var roles = loadJsonContent('roles.json')

@export()
type SuggestedRoleName = items(roles)

@export()
func suggestedRoleId(name SuggestedRoleName) string => roles[name]
jeskew commented 1 month ago

I like this suggestion! The implementation would likely be a utility type (the <...> syntax introduced for resource-derived types), and I think we'd need a different name to disambiguate from the items function. Perhaps we could borrow TypeScript's terminology and call this keyof?:

type obj = {
  foo: string
  bar: string
}

@sealed()
type sealedObj = {
  foo: string
  bar: string
}

type objKey = keyof<obj>              // == 'foo' | 'bar' | string
type sealedObjKey = keyof<sealedObj>  // == 'foo' | 'bar'

I think we might need a typeof utility type to make this work with the example supplied, though, since roles is a value rather than a type:

// do scale
var roles = loadJsonContent('roles.json')

@export()
type SuggestedRoleName = keyof<typeof<roles>>

@export()
func suggestedRoleId(name SuggestedRoleName) string => roles[name]