Condividi tramite


Tipi di dati definiti dall'utente in Bicep

Informazioni su come creare i tipi di dati definiti dall'utente in Bicep. Per i tipi di dati definiti dal sistema, vedere Tipi di dati. L'uso dei tipi di dati definiti dall'utente abilita automaticamente la generazione di codice della versione 2.0 del linguaggio.

Per usare questa funzionalità è necessaria l'interfaccia della riga di comando Bicep versione 0.12.X o successiva .

Definire i tipi

È possibile usare l'istruzione type per creare tipi di dati definiti dall'utente. È anche possibile usare espressioni di tipo in alcune posizioni per definire tipi personalizzati.

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

L'elemento @allowed decorator è consentito solo nelle param istruzioni . Per dichiarare un tipo con un set di valori predefiniti in un oggetto type, usare la sintassi del tipo di unione.

Le espressioni di tipo valide includono:

  • I riferimenti simbolici sono identificatori che fanno riferimento a un tipo di ambiente (ad esempio string o int) o a un simbolo di tipo definito dall'utente dichiarato in un'istruzione type:

    // Bicep data type reference
    type myStringType = string
    
    // user-defined type reference
    type myOtherStringType = myStringType
    
  • I valori letterali primitivi, incluse stringhe, interi e booleani, sono espressioni di tipo valide. Ad esempio:

    // 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
    
  • È possibile dichiarare i tipi di matrice aggiungendo [] a qualsiasi espressione di tipo valida:

    // 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)[]
    
  • I tipi di oggetto contengono zero o più proprietà tra parentesi graffe:

    type storageAccountConfigType = {
      name: string
      sku: string
    }
    

    Ogni proprietà in un oggetto è costituita da una chiave e da un valore separato da due punti :. La chiave può essere qualsiasi stringa, con valori nonidentifier racchiusi tra virgolette. Il valore può essere qualsiasi tipo di espressione.

    Le proprietà sono obbligatorie a meno che non abbiano un marcatore ? di facoltatività dopo il valore della proprietà. Ad esempio, la proprietà sku nell'esempio seguente è facoltativa:

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

    È possibile usare elementi Decorator nelle proprietà. È possibile usare un asterisco (*) per fare in modo che tutti i valori richiedano un vincolo. È possibile definire altre proprietà usando *. In questo esempio viene creato un oggetto che richiede una chiave di tipo int denominata id. Tutte le altre voci nell'oggetto devono essere un valore stringa di almeno 10 caratteri.

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

    L'esempio seguente illustra come usare la sintassi dei tipi di unione per elencare un set di valori predefiniti:

    type directions = 'east' | 'south' | 'west' | 'north'
    
    type obj = {
      level: 'bronze' | 'silver' | 'gold'
    }
    
  • I tipi di oggetto possono usare ricorsione diretta o indiretta se almeno la gamba del percorso verso il punto di ricorsione è facoltativa. Ad esempio, la definizione myObjectType nell'esempio seguente è valida perché la proprietà recursiveProp ricorsiva diretta è facoltativa:

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

    La definizione di tipo seguente non sarebbe valida perché nessuno di level1, level2, level3, level4, o level5 è facoltativo.

    type invalidRecursiveObjectType = {
      level1: {
        level2: {
          level3: {
            level4: {
              level5: invalidRecursiveObjectType
            }
          }
        }
      }
    }
    
  • È possibile usare operatori unari Bicep con valori letterali interi e booleani o riferimenti a simboli letterali booleani o interi:

    type negativeIntLiteral = -10
    type negatedIntReference = -negativeIntLiteral
    
    type negatedBoolLiteral = !true
    type negatedBoolReference = !negatedBoolLiteral
    
  • Le unioni possono includere un numero qualsiasi di espressioni di tipo letterale. I tipi di unione vengono convertiti nel vincolo allowed-value (valore consentito) in Bicep, quindi solo i valori letterali sono consentiti come membri.

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

È possibile usare espressioni di tipo nell'istruzione type ed è anche possibile usare espressioni di tipo per creare tipi di dati definiti dall'utente, come illustrato nelle posizioni seguenti:

  • Come clausola type di un'istruzione param. Ad esempio:

    param storageAccountConfig {
      name: string
      sku: string
    }
    
  • Dopo : in una proprietà del tipo di oggetto. Ad esempio:

    param storageAccountConfig {
     name: string
      properties: {
        sku: string
      }
    } = {
      name: 'store$(uniqueString(resourceGroup().id)))'
      properties: {
        sku: 'Standard_LRS'
      }
    }
    
  • Prima di [] in un'espressione di tipo matrice. Ad esempio:

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

Un tipico file Bicep per creare un account di archiviazione è simile al seguente:

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

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

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

Con i tipi di dati definiti dall'utente, può essere simile al seguente:

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

Usare elementi Decorator

Gli elementi Decorator vengono scritti nel formato @expression e vengono posizionati sopra le dichiarazioni del tipo di dati definito dall'utente. La tabella seguente illustra gli elementi Decorator disponibili per i tipi di dati definiti dall'utente.

Decorator Applica a Argomento Descrizione
description tutto string Fornire descrizioni per il tipo di dati definito dall'utente.
discriminator oggetto string Usare questo elemento decorator per assicurarsi che la sottoclasse corretta sia identificata e gestita.
export tutto Nessuno Indica che il tipo di dati definito dall'utente è disponibile per l'importazione da un altro file Bicep.
maxLength array, stringa int Lunghezza massima per i tipi di dati stringa e matrice. Il valore è inclusivo.
maxValue int int Valore massimo per i tipi di dati integer. Questo valore è inclusivo.
metadata tutto oggetto Proprietà personalizzate da applicare ai tipi di dati. Può includere una proprietà description equivalente all'elemento decorator della descrizione.
minLength array, stringa int Lunghezza minima per i tipi di dati stringa e matrice. Il valore è inclusivo.
minValue int int Valore minimo per i tipi di dati Integer. Questo valore è inclusivo.
sealed oggetto Nessuno Elevare BCP089 da un avviso a un errore quando un nome di proprietà di un tipo di dati definito dall'utente è probabilmente un errore di digitazione. Per altre informazioni, vedere Elevare il livello di errore.
sicuro stringa, oggetto Nessuno Contrassegna i tipi come sicuri. Il valore di un tipo sicuro non viene salvato nella cronologia di distribuzione e non viene registrato. Per altre informazioni, vedere Proteggere stringhe e oggetti.

I decorator si trovano nello spazio dei nomi sys. Se è necessario distinguere un decorator da un altro elemento con lo stesso nome, anteporre al decorator con sys. Ad esempio, se il file Bicep include una variabile denominata description, è necessario aggiungere lo sys spazio dei nomi quando si usa l'elemento description Decorator.

Discriminatore

Vedere Tipo di dati Unione con tag.

Descrizione

Aggiungere una descrizione al tipo di dati definito dall'utente. È possibile usare elementi Decorator nelle proprietà. Ad esempio:

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

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

È possibile usare il testo in formato Markdown per il testo della descrizione.

Esportazione

Usare @export() per condividere il tipo di dati definito dall'utente con altri file Bicep. Per altre informazioni, vedere Esportare variabili, tipi e funzioni.

Vincoli sui numeri interi

È possibile impostare valori minimi e massimi per il tipo integer. È possibile impostare uno o entrambi i vincoli.

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

Vincoli di lunghezza

È possibile specificare lunghezze minime e massime per le definizioni dei tipi stringa e array. È possibile impostare uno o entrambi i vincoli. Per le stringhe, la lunghezza indica il numero di caratteri. Per le matrici, la lunghezza indica il numero di elementi nell'array.

Nell'esempio seguente vengono dichiarati due tipi. Un tipo è per un nome di account di archiviazione che deve avere da 3 a 24 caratteri. L'altro tipo è una matrice che deve avere da uno a cinque elementi.

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

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

Metadati UFX

Se si dispone di proprietà personalizzate da applicare a un tipo di dati definito dall'utente, aggiungere un elemento Decorator di metadati. All'interno dei metadati definire un oggetto con i nomi e i valori personalizzati. L'oggetto definito per i metadati può contenere proprietà di qualsiasi nome e tipo.

È possibile usare questo elemento Decorator per tenere traccia delle informazioni sul tipo di dati che non hanno senso aggiungere alla descrizione.

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

Quando si fornisce un decorator @metadata() con una proprietà in conflitto con un altro decorator, tale decorator ha sempre la precedenza su qualsiasi elemento nel decorator @metadata(). La proprietà in conflitto all'interno del @metadata() valore è quindi ridondante e viene sostituita. Per altre informazioni, vedere Nessun metadati in conflitto.

Sealed

Vedere Elevare il livello di errore.

Tipi protetti

È possibile contrassegnare un tipo di dati stringa o oggetto definito dall'utente come sicuro. Il valore di un tipo sicuro non viene salvato nella cronologia di distribuzione e non viene registrato.

@secure()
type demoPassword string

@secure()
type demoSecretObject object

Elevare il livello di errore

Per impostazione predefinita, la dichiarazione di un tipo di oggetto in Bicep consente di accettare più proprietà di qualsiasi tipo. Ad esempio, il bicep seguente è valido ma genera un avviso di [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'
}

L'avviso informa che il anObject tipo non include una proprietà denominata otionalProperty. Anche se non si verificano errori durante la distribuzione, il compilatore Bicep presuppone che otionalProperty si tratti di un errore di ortografia e che si intende usare optionalProperty ma che sia stato digitato in modo non corretto. Bicep segnala l'incoerenza.

Per inoltrare questi avvisi agli errori, applicare l'elemento Decorator @sealed() al tipo di oggetto:

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

Per ottenere gli stessi risultati, applicare l'elemento decorator @sealed() alla dichiarazione param:

type anObject = {
  property: string
  optionalProperty: string?
}
 
@sealed() 
param aParameter anObject = {
  property: 'value'
  otionalProperty: 'value'
}

Il motore di distribuzione di Azure Resource Manager controlla anche i tipi sealed per altre proprietà. Se si specificano proprietà aggiuntive per i parametri sealed, viene generato un errore di convalida che causa l'esito negativo della distribuzione. Ad esempio:

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

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

Tipo di dati unione con tag

Per dichiarare un tipo di dati unione con tag personalizzati all'interno di un file Bicep, è possibile inserire un’espressione Decorator discriminator sopra una dichiarazione di tipo definita dall'utente. Per usare questo elemento decorator è necessaria l’interfaccia della riga di comando di Bicep versione 0.21.X o successiva. Nell'esempio seguente viene illustrato come dichiarare un tipo di dati unione con tag:

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

Per altre informazioni, vedere Tipo di dati unione con tag personalizzati.

Per un elenco dei tipi di dati Bicep, vedere Tipi di dati.