Tipos de dados definidos pelo usuário no Bicep

Saiba como criar tipos de dados definidos pelo usuário no Bicep. Para tipos de dados definidos pelo sistema, consulte Tipos de dados. O uso de tipos de dados definidos pelo usuário habilita automaticamente a geração de código da versão de linguagem 2.0.

A CLI do Bicep versão 0.12.X ou superior é necessária para usar esse recurso.

A regra do linter use-user-defined-types incentiva o uso de tipos de dados definidos pelo usuário em vez dos tipos genéricos object ou array.

Defina os tipos

Use a type instrução para criar tipos de dados definidos pelo usuário. Você também pode usar expressões de tipo em alguns locais para definir tipos personalizados.

@<decorator>(<argument>)
type <user-defined-data-type-name> = <type-expression>

O decorador @allowed só é permitido em declarações param. Para declarar um tipo com um conjunto de valores predefinidos em um type, use a sintaxe de tipo união.

Expressões de tipo válidas incluem:

Referências simbólicas

Referências simbólicas são identificadores que se referem a um tipo de ambiente (como string ou int) ou a um símbolo de tipo definido pelo usuário declarado em uma type instrução.

// Bicep data type reference
type myStringType = string

// user-defined type reference
type myOtherStringType = myStringType

Literais primitivos

Literais primitivos, incluindo cadeias de caracteres, inteiros e boolianos, são expressões de tipo válidas. Por exemplo:

// 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

Tipos de array

Você pode declarar tipos de matriz acrescentando [] a qualquer expressão de tipo válida. Por exemplo:

// 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)[]

Tipos de união

Um tipo de união permite que você crie um tipo combinado que consiste em um conjunto de subtipos. Um valor corresponde ao tipo se corresponder a qualquer um dos subtipos. Use o operador pipe (|) para separar os tipos de membro individuais. O Bicep converte tipos de união na restrição de valores permitidos, portanto, apenas literais são permitidos como membros. As uniões podem incluir qualquer número de expressões do tipo literal.

type directions = 'east' | 'south' | 'west' | 'north'

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

Você pode declarar tipos de união embutidos, e um membro pode ser uma referência a outro símbolo tipado como literal.

Uniões de tipo misto

Os tipos de membro não precisam ser do mesmo tipo de literal. Uma união pode combinar literais de cadeia de caracteres, inteiro, booliano, objeto e null.

type mixedType = 'fizz' | 42 | { an: 'object' } | null

Note

O | operador também é usado em vários cenários relacionados documentados em outros lugares neste artigo:

Tipos de objeto

Os tipos de objeto contêm zero ou mais propriedades entre colchetes:

type storageAccountConfigType = {
  name: string
  sku: string
}

Cada propriedade em um objeto consiste em uma chave e um valor, separados por dois pontos :. A chave pode ser qualquer cadeia de caracteres, com valores não identificadores entre aspas. O valor pode ser qualquer tipo de expressão.

As propriedades são necessárias, a menos que tenham um marcador de opcionalidade ? após o valor da propriedade. Por exemplo, a propriedade sku no seguinte exemplo é opcional:

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

Você pode usar decoradores em propriedades. Você pode usar um asterisco (*) para fazer com que todos os valores exijam uma restrição. Você pode definir mais propriedades usando *. Este exemplo cria um objeto que requer uma chave do tipo int chamado id. Todas as outras entradas no objeto precisam ter um valor de cadeia de caracteres com pelo menos dez caracteres.

type obj = {
  @description('The object ID')
  id: int

  @description('Additional properties')
  @minLength(10)
  *: string
}

O exemplo a seguir mostra como usar a sintaxe do tipo de união para listar um conjunto de valores predefinidos:

type directions = 'east' | 'south' | 'west' | 'north'

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

Recursão

Os tipos de objetos podem usar recursão direta ou indireta, desde que pelo menos um dos caminhos para o ponto de recursão seja opcional. Por exemplo, a definição myObjectType no seguinte exemplo é válida porque a propriedade recursiveProp recursiva diretamente é opcional:

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

A definição de tipo a seguir não é válida porque nenhuma de level1, level2, level3, level4ou level5 é opcional.

type invalidRecursiveObjectType = {
  level1: {
    level2: {
      level3: {
        level4: {
         level5: invalidRecursiveObjectType
        }
      }
    }
  }
}

Operadores unários

Use operadores unários do Bicep com literais inteiros e boolianos ou referências a símbolos tipados como literais inteiros ou boolianos.

type negativeIntLiteral = -10
type negatedIntReference = -negativeIntLiteral

type negatedBoolLiteral = !true
type negatedBoolReference = !negatedBoolLiteral

As uniões podem incluir qualquer número de expressões do tipo literal. O Bicep converte tipos de união na restrição de valores permitidos, portanto, apenas literais são permitidos como membros.

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

Use expressões de tipo na instrução type. Você também pode usar expressões de tipo para criar tipos de dados definidos pelo usuário, conforme mostrado nos locais a seguir.

  • Como a cláusula de tipo de uma instrução param. Por exemplo:

    param storageAccountConfig {
      name: string
      sku: string
    }
    
  • Seguindo o : em uma propriedade de tipo de objeto. Por exemplo:

    param storageAccountConfig {
    name: string
      properties: {
        sku: string
      }
    } = {
      name: 'store$(uniqueString(resourceGroup().id)))'
      properties: {
        sku: 'Standard_LRS'
      }
    }
    
  • Anterior a [] em uma expressão de tipo de matriz. Por exemplo:

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

Um arquivo Bicep típico para criar uma conta de armazenamento é semelhante a:

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

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

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

Com tipos de dados definidos pelo usuário, isso pode ter a seguinte aparência:

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@2025-06-01' = {
  name: storageAccountConfig.name
  location: location
  sku: {
    name: storageAccountConfig.sku
  }
  kind: 'StorageV2'
}

Usar decoradores

Escreva decoradores no formato @expression e coloque-os acima das declarações do tipo de dados definido pelo usuário. A tabela a seguir mostra os decoradores disponíveis para os tipos de dados definidos pelo usuário.

Decorador Aplicar a Argumento Descrição
description todos cadeia Fornece descrições para o tipo de dados definido pelo usuário.
discriminador objeto cadeia Use esse decorador para garantir que a subclasse correta seja identificada e gerenciada.
export todos none Indica que o tipo de dados definido pelo usuário está disponível para importação por outro arquivo Bicep.
maxLength matriz, cadeia de caracteres INT O comprimento máximo de tipos de dados de matriz e cadeia de caracteres. O valor é inclusivo.
maxValue INT INT O valor máximo dos tipos de dados inteiros. Esse valor é inclusivo.
metadados todos objeto Propriedades personalizadas a serem aplicadas aos tipos de dados. Pode incluir uma propriedade de descrição equivalente ao decorador da descrição.
minLength matriz, cadeia de caracteres INT O comprimento mínimo de tipos de dados de matriz e cadeia de caracteres. O valor é inclusivo.
minValue INT INT O valor mínimo dos tipos de dados inteiros. Esse valor é inclusivo.
selado objeto none Eleve o BCP089 de aviso para erro quando um nome de propriedade de um tipo de dados definido pelo usuário for provavelmente um erro de digitação. Para obter mais informações, consulte Elevar nível de erro.
secure cadeia de caracteres, objeto none Marca os tipos como seguros. O valor de um tipo seguro não é salvo no histórico de implantação e não é registrado em log. Para obter mais informações, confira Proteger cadeias de caracteres e objetos.

Os decoradores estão no namespace sys. Se você precisar diferenciar um decorador de outro item com o mesmo nome, preceda o decorador com sys. Por exemplo, se o arquivo Bicep incluir uma variável chamada description, você precisará adicionar o namespace sys ao usar o decorador description.

Discriminador

Confira Tipo de dado de união com marcação.

Descrição

Adicione uma descrição ao tipo de dados definido pelo usuário. Você pode usar decoradores em propriedades. Por exemplo:

@description('Define a new object type.')
type obj = {
  @description('The object ID')
  id: int

  @description('Additional properties')
  @minLength(10)
  *: string
}

Você pode usar o texto formatado por Markdown para o texto de descrição.

Exportação

Use @export() para compartilhar o tipo de dados definido pelo usuário com outros arquivos Bicep. Para obter mais informações, confira Exportar variáveis, tipos e funções.

Restrições do inteiro

Defina valores mínimos e máximos para o tipo inteiro. É possível definir uma restrição ou as duas.

@minValue(1)
@maxValue(12)
type month int

Restrições de comprimento

Especifique comprimentos mínimos e máximos para tipos de cadeia de caracteres e matriz. É possível definir uma restrição ou as duas. Nas cadeias de caracteres, o comprimento indica o número de caracteres. Nas matrizes, o comprimento indica o número de itens da matriz.

O exemplo a seguir declara dois tipos. Um tipo destina-se a um nome de conta de armazenamento, que precisa ter entre 3 e 24 caracteres. O outro tipo é uma matriz, que precisa ter entre um e cinco itens.

@minLength(3)
@maxLength(24)
type storageAccountName string

@minLength(1)
@maxLength(5)
type appNames array

Metadados

Se você tiver propriedades personalizadas que deseja aplicar a um tipo de dados definido pelo usuário, adicione um decorador de metadados. Dentro dos metadados, defina um objeto com os nomes e os valores personalizados. O objeto que você define para os metadados pode conter propriedades de qualquer nome e tipo.

Use este decorador para acompanhar informações sobre o tipo de dados que não faz sentido adicionar à descrição.

@description('Configuration values that are applied when the application starts.')
@metadata({
  source: 'database'
  contact: 'Web team'
})
type settings object

Quando você fornece a um decorador @metadata() uma propriedade que entra em conflito com outro decorador, a propriedade conflitante dentro do valor de @metadata() torna-se redundante e é substituída. Para obter mais informações, consulte Sem metadados conflitantes.

Selado

Consulte Elevar nível de erro.

Tipos seguros

Você pode marcar um tipo de dados definido pelo usuário de cadeia de caracteres ou objeto como seguro. O valor de um tipo seguro não é salvo no histórico de implantação e não é registrado em log.

@secure()
type demoPassword string

@secure()
type demoSecretObject object

Elevar o nível de erro

Por padrão, a declaração de um tipo de objeto no Bicep permite que ele aceite propriedades adicionais de qualquer tipo. Por exemplo, o Bicep a seguir é válido, mas gera um aviso de [BCP089] The property "otionalProperty" is not allowed on objects of type "{ property: string, optionalProperty: null | string }". Did you mean "optionalProperty"?:

type anObject = {
  property: string
  optionalProperty: string?
}

param aParameter anObject = {
  property: 'value'
  otionalProperty: 'value'
}

O aviso informa que o tipo anObject não inclui uma propriedade chamada otionalProperty. Embora nenhum erro ocorra durante a implantação, o compilador Bicep pressupõe que otionalProperty seja um erro de digitação e que você pretendia usar optionalProperty, mas o escreveu incorretamente. O Bicep alerta você para a inconsistência.

Para transformar esses avisos em erros, aplique o decorador @sealed() ao tipo de objeto:

@sealed()
type anObject = {
  property: string
  optionalProperty?: string
}

Você obtém os mesmos resultados aplicando o decorador @sealed() à declaração param:

type anObject = {
  property: string
  optionalProperty: string?
}

@sealed()
param aParameter anObject = {
  property: 'value'
  otionalProperty: 'value'
}

O mecanismo de implantação do Azure Resource Manager também verifica os tipos selados para outras propriedades. Fornecer quaisquer propriedades extras para parâmetros selados resulta em um erro de validação, causando a falha na implantação. Por exemplo:

@sealed()
type anObject = {
  property: string
}

param aParameter anObject = {
  property: 'value'
  optionalProperty: 'value'
}

Tipo de dados de união marcado

Para declarar um tipo de dados de união com tag personalizada em um arquivo Bicep, você pode colocar um decorador discriminator acima de uma declaração de tipo definida pelo usuário. A CLI do Bicep versão 0.21.X ou superior é necessária para usar esse decorador. O exemplo a seguir mostra como declarar um tipo de dados de união marcado:

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

Para obter mais informações, veja Tipo de dados de união com marcas personalizadas.

Tipos derivados de recursos

Bicep permite derivar tipos diretamente dos esquemas de recursos do Azure por meio dos constructos resourceInput<> e resourceOutput<>. Usando tipos derivados de recursos, você pode verificar parâmetros e variáveis em uma parte de um corpo de recurso em vez de usar um tipo personalizado. Para usar esses constructos, você precisa Bicep CLI versão 0.34.1 ou superior.

Os modelos podem reutilizar tipos de recursos onde quer que um tipo seja esperado.

resourceInput<'type@version'>
  • resourceInput<>: representa as propriedades graváveis de um tipo de recurso, removendo todas as propriedades marcadas como ReadOnly no esquema de modelo do ARM. Ele usa o tipo que você precisa passar para a declaração de recurso.
resourceOutput<'type@version'>
  • resourceOutput<>: representa as propriedades legíveis de um tipo de recurso, removendo todas as propriedades marcadas como WriteOnly no esquema de modelo do ARM. Ele corresponde ao tipo de valor retornado depois que o recurso é provisionado.

Você pode aplicar resourceInput<> ou resourceOutput<> extrair apenas uma parte de um esquema de recurso. Por exemplo, para digitar uma variável ou parâmetro com base apenas no kind ou properties de uma conta de armazenamento:

type accountKind = resourceInput<'Microsoft.Storage/storageAccounts@2024-01-01'>.kind

O exemplo anterior é equivalente a:

type accountKind = 'BlobStorage' | 'BlockBlobStorage' | 'FileStorage' | 'Storage' | 'StorageV2'

O exemplo a seguir mostra como usar resourceInput<> para criar um parâmetro tipado com base no properties recurso de uma conta de armazenamento. Essa abordagem define um parâmetro que corresponde às propriedades graváveis de uma conta de armazenamento, como accessTier, minimumTlsVersione outras propriedades:

// Typed parameter using the .properties path of a storage account
param storageAccountProps resourceInput<'Microsoft.Storage/storageAccounts@2023-01-01'>.properties = {
  accessTier: 'Hot'
  minimumTlsVersion: 'TLS1_2'
  allowBlobPublicAccess: false
  supportsHttpsTrafficOnly: true
}

// Resource declaration using the typed parameter
resource storageAccount 'Microsoft.Storage/storageAccounts@2025-06-01' = {
  name: 'mystorageacct123'
  location: resourceGroup().location
  sku: {
    name: 'Standard_LRS'
  }
  kind: 'StorageV2'
  properties: storageAccountProps
}

O exemplo a seguir mostra como usar resourceOutput<> para criar uma saída tipada com base no recurso primaryEndPoints de uma conta de armazenamento.

output storageEndpoints resourceOutput<'Microsoft.Storage/storageAccounts@2024-01-01'>.properties.primaryEndpoints = ...

Ao contrário dos tipos de dados definidos pelo usuário, Bicep verifica os tipos derivados de recursos quando você edita ou compila um arquivo, mas o serviço ARM não os verifica.

Para obter uma lista dos tipos de data do Bicep, consulte Tipos de dados.