Определяемые пользователем типы данных в Bicep

Узнайте, как использовать определяемые пользователем типы данных в Bicep.

Для использования этой функции требуется интерфейс командной строки Bicep версии 0.12.X или более поздней .

Синтаксис определяемого пользователем типа данных

Инструкцию type можно использовать для определения определяемых пользователем типов данных. Кроме того, можно также использовать выражения типов в некоторых местах для определения пользовательских типов.

type <user-defined-data-type-name> = <type-expression>

Примечание.

Декоратор @allowed разрешен только для param инструкций. Чтобы объявить, что свойство должно быть одним из наборов предопределенных значений в инструкции type или output операторе, используйте синтаксис типа объединения. Синтаксис типа объединения также может использоваться в param инструкциях.

Допустимые выражения типов включают:

  • Символьные ссылки — это идентификаторы, ссылающиеся на внешний тип (напримерstring, илиint) или символ определяемого пользователем типа, объявленный в инструкцииtype:

    // Bicep data type reference
    type myStringType = string
    
    // user-defined type reference
    type myOtherStringType = myStringType
    
  • Примитивные литералы, включая строки, целые числа и логические выражения, являются допустимыми выражениями типов. Например:

    // a string type with three allowed values.
    type myStringLiteralType = 'bicep' | 'arm' | 'azure'
    
    // an integer type with one allowed value
    type myIntLiteralType = 10
    
    // an boolean type with one allowed value
    type myBoolLiteralType = true
    
  • Типы массивов можно объявить, суффиксируя [] любое допустимое выражение типа:

    // A string type array
    type myStrStringsType1 = string[]
    // A string type array with three allowed values
    type myStrStringsType2 = ('a' | 'b' | 'c')[]
    
    type myIntArrayOfArraysType = int[][]
    
    // A mixed-type array with four allowed values
    type myMixedTypeArrayType = ('fizz' | 42 | {an: 'object'} | null)[]
    
  • Типы объектов содержат ноль или больше свойств между фигурными скобками:

    type storageAccountConfigType = {
      name: string
      sku: string
    }
    

    Каждое свойство в объекте состоит из ключа и значения. Ключ и значение разделены двоеточием :. Ключ может быть любой строкой (значения, которые не будут допустимым идентификатором должны быть заключены в кавычки), а значение может быть любым выражением синтаксиса типа.

    Свойства требуются, если они не имеют маркера необязательности ? после значения свойства. Например, sku свойство в следующем примере является необязательным:

    type storageAccountConfigType = {
      name: string
      sku: string?
    }
    

    Декораторы могут использоваться для свойств. * может использоваться для создания всех значений, требующих ограничения. При использовании *все еще могут быть определены дополнительные свойства. В этом примере создается объект, требующий ключа типа int с именем id, и что все остальные записи в объекте должны быть строковым значением не менее 10 символов.

    type obj = {
      @description('The object ID')
      id: int
    
      @description('Additional properties')
      @minLength(10)
      *: string
    }
    

    В следующем примере показано, как использовать синтаксис типа объединения для перечисления набора предопределенных значений:

    type obj = {
      level: 'bronze' | 'silver' | 'gold'
    }
    

    Рекурсия

    Типы объектов могут использовать прямую или непрямую рекурсию, если по крайней мере нога пути к точке рекурсии является необязательным. Например, определение в следующем примере допустимо, myObjectType так как непосредственно рекурсивное свойство является необязательным recursiveProp :

    type myObjectType = {
      stringProp: string
      recursiveProp: myObjectType?
    }
    

    Но следующее определение типа не будет допустимым, так как ни один level1из , level2или level3level4level5 необязательный.

    type invalidRecursiveObjectType = {
      level1: {
        level2: {
          level3: {
            level4: {
              level5: invalidRecursiveObjectType
            }
          }
        }
      }
    }
    
  • Унарные операторы Bicep можно использовать с целыми числами и логическими литералами или ссылками на целые или логические символы, типизированные литералами:

    type negativeIntLiteral = -10
    type negatedIntReference = -negativeIntLiteral
    
    type negatedBoolLiteral = !true
    type negatedBoolReference = !negatedBoolLiteral
    
  • Профсоюзы могут включать любое количество литеральных выражений. Типы объединения превратятся в ограничение разрешенного значения в Bicep, поэтому только литералы разрешены в качестве членов.

    type oneOfSeveralObjects = {foo: 'bar'} | {fizz: 'buzz'} | {snap: 'crackle'}
    type mixedTypeArray = ('fizz' | 42 | {an: 'object'} | null)[]
    

Помимо использования в инструкции type , выражения типов также можно использовать в этих местах для создания определяемых пользователем типов данных:

  • В качестве предложения типа инструкции param . Например:

    param storageAccountConfig {
      name: string
      sku: string
    }
    
  • : После свойства типа объекта. Например:

    param storageAccountConfig {
     name: string
      properties: {
        sku: string
      }
    } = {
      name: 'store$(uniqueString(resourceGroup().id)))'
      properties: {
        sku: 'Standard_LRS'
      }
    }
    
  • Перед выражением [] типа массива. Например:

    param mixedTypeArray ('fizz' | 42 | {an: 'object'} | null)[]
    

Типичный Bicep-файл для создания учетной записи хранения выглядит следующим образом:

param location string = resourceGroup().location
param storageAccountName string

@allowed([
  'Standard_LRS'
  'Standard_GRS'
])
param storageAccountSKU string = 'Standard_LRS'

resource storageAccount 'Microsoft.Storage/storageAccounts@2022-09-01' = {
  name: storageAccountName
  location: location
  sku: {
    name: storageAccountSKU
  }
  kind: 'StorageV2'
}

С помощью определяемых пользователем типов данных он может выглядеть следующим образом:

param location string = resourceGroup().location

type storageAccountSkuType = 'Standard_LRS' | 'Standard_GRS'

type storageAccountConfigType = {
  name: string
  sku: storageAccountSkuType
}

param storageAccountConfig storageAccountConfigType

resource storageAccount 'Microsoft.Storage/storageAccounts@2022-09-01' = {
  name: storageAccountConfig.name
  location: location
  sku: {
    name: storageAccountConfig.sku
  }
  kind: 'StorageV2'
}

Объявление типа объединения с тегами

Чтобы объявить настраиваемый тип данных с тегами объединения в файле Bicep, можно поместить дискриминационный декоратор над объявлением определяемого пользователем типа. Для использования этого декоратора требуется интерфейс командной строки Bicep версии 0.21.X или более поздней . Синтаксис:

@discriminator('<propertyName>')

Дискриминационный декоратор принимает один параметр, который представляет имя общей собственности среди всех членов профсоюза. Это имя свойства должно быть обязательным строковым литералом для всех элементов и учитывает регистр. Значения дискриминированного свойства членов профсоюза должны быть уникальными в нечувствительной манере.

В следующем примере показано, как объявить тип тегированного объединения:

type FooConfig = {
  type: 'foo'
  value: int
}

type BarConfig = {
  type: 'bar'
  value: bool
}

@discriminator('type')
type ServiceConfig = FooConfig | BarConfig | { type: 'baz', *: string }

param serviceConfig ServiceConfig = { type: 'bar', value: true }

output config object = serviceConfig

Значение параметра проверяется на основе значения дискриминации свойства. В предыдущем примере, если значение параметра serviceConfig имеет тип foo, он проходит проверку с помощью типа FooConfig. Аналогичным образом, если значение параметра имеет строку типа, проверка выполняется с помощью типа BarConfig, и этот шаблон продолжается для других типов.

Импорт типов между файлами Bicep (предварительная версия)

Для использования этой функции импорта во время компиляции требуется интерфейс командной строки Bicep версии 0.21.X или более поздней . Экспериментальный флаг compileTimeImports должен быть включен из файла конфигурации Bicep.

В другие шаблоны можно импортировать только определяемые пользователем типы данных, которые несут @export() декоратор. В настоящее время этот декоратор можно использовать только для type инструкций.

В следующем примере можно импортировать два пользовательских типа данных из других шаблонов:

@export()
type myStringType = string

@export()
type myOtherStringType = myStringType

Дополнительные сведения см. в разделе "Импорт определяемых пользователем типов данных".

Следующие шаги

  • Список типов данных Bicep см. в разделе "Типы данных".