Dela via


Användardefinierade datatyper i Bicep

Lär dig hur du skapar användardefinierade datatyper i Bicep. Information om systemdefinierade datatyper finns i Datatyper.

Bicep CLI version 0.12.X eller senare krävs för att använda den här funktionen.

Syntax

Du kan använda -instruktionen type för att skapa användardefinierade datatyper. Dessutom kan du också använda typuttryck på vissa platser för att definiera anpassade typer.

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

Dekoratören @allowed är endast tillåten för param instruktioner. Om du vill deklarera en typ med en uppsättning fördefinierade värden i en typeanvänder du syntax för unionstyp.

De giltiga typuttrycken är:

  • Symboliska referenser är identifierare som refererar till en omgivande typ (som string eller int) eller en användardefinierad typsymbol som deklareras i en type instruktion:

    // Bicep data type reference
    type myStringType = string
    
    // user-defined type reference
    type myOtherStringType = myStringType
    
  • Primitiva literaler, inklusive strängar, heltal och booleska värden, är giltiga typuttryck. Till exempel:

    // 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
    
  • Du kan deklarera matristyper genom att lägga [] till valfritt giltigt typuttryck:

    // 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)[]
    
  • Objekttyper innehåller noll eller fler egenskaper mellan klammerparenteser:

    type storageAccountConfigType = {
      name: string
      sku: string
    }
    

    Varje egenskap i ett objekt består av en nyckel och ett värde, avgränsat med ett kolon :. Nyckeln kan vara valfri sträng, med värden som inte är identifierade inom citattecken, och värdet kan vara vilken typ av uttryck som helst.

    Egenskaper krävs om de inte har en valfrihetsmarkör ? efter egenskapsvärdet. Egenskapen i följande exempel är till exempel sku valfri:

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

    Dekoratörer kan användas på egenskaper. * kan användas för att göra så att alla värden kräver en begränsning. Ytterligare egenskaper kan fortfarande definieras när du använder *. Det här exemplet skapar ett objekt som kräver en nyckel av typen int med namnet ID och att alla andra poster i objektet måste vara ett strängvärde som är minst 10 tecken långt.

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

    Följande exempel visar hur du använder syntaxen för unionstyp för att visa en uppsättning fördefinierade värden:

    type directions = 'east' | 'south' | 'west' | 'north'
    
    type obj = {
      level: 'bronze' | 'silver' | 'gold'
    }
    

    Rekursion

    Objekttyper kan använda direkt eller indirekt rekursion så länge som minst en del av sökvägen till rekursionspunkten är valfri. Definitionen i följande exempel är till exempel myObjectType giltig eftersom den direkt rekursiva recursiveProp egenskapen är valfri:

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

    Men följande typdefinition skulle inte vara giltig eftersom inget av level1, level2, level3, level4eller level5 är valfritt.

    type invalidRecursiveObjectType = {
      level1: {
        level2: {
          level3: {
            level4: {
              level5: invalidRecursiveObjectType
            }
          }
        }
      }
    }
    
  • Bicep unary-operatorer kan användas med heltal och booleska literaler eller referenser till heltal eller booleska literaltypade symboler:

    type negativeIntLiteral = -10
    type negatedIntReference = -negativeIntLiteral
    
    type negatedBoolLiteral = !true
    type negatedBoolReference = !negatedBoolLiteral
    
  • Unioner kan innehålla valfritt antal literaltypade uttryck. Union-typer översätts till villkoret allowed-value i Bicep, så endast literaler tillåts som medlemmar.

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

Förutom att användas i -instruktionen type kan typuttryck också användas på dessa platser för att skapa användardefinierade datatyper:

  • Som typsatsen för en param -instruktion. Till exempel:

    param storageAccountConfig {
      name: string
      sku: string
    }
    
  • : Följ egenskapen i en objekttyp. Till exempel:

    param storageAccountConfig {
     name: string
      properties: {
        sku: string
      }
    } = {
      name: 'store$(uniqueString(resourceGroup().id)))'
      properties: {
        sku: 'Standard_LRS'
      }
    }
    
  • [] Före i ett matristyputtryck. Till exempel:

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

En typisk Bicep-fil för att skapa ett lagringskonto ser ut så här:

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'
}

Genom att använda användardefinierade datatyper kan det se ut så här:

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'
}

Höja felnivån

Om du deklarerar en objekttyp i Bicep kan den som standard acceptera ytterligare egenskaper av vilken typ som helst. Följande Bicep är till exempel giltigt men genererar en varning om [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'
}

Varningen informerar dig om att typen anObject inte innehåller en egenskap med namnet otionalProperty. Även om inga fel inträffar under distributionen förutsätter Bicep-kompilatorn att otionalProperty är ett stavfel, att du avsåg att använda optionalProperty men felstavade det och varnar dig för inkonsekvensen.

Om du vill eskalera dessa varningar till fel använder du dekoratören @sealed() på objekttypen:

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

Du får samma resultat genom att tillämpa dekoratören @sealed() på deklarationen param :

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

ARM-distributionsmotorn kontrollerar också förseglade typer för ytterligare egenskaper. Om du anger eventuella extra egenskaper för förseglade parametrar resulterar det i ett valideringsfel, vilket gör att distributionen misslyckas. Till exempel:

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

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

Taggad union-datatyp

Om du vill deklarera en anpassad taggad union-datatyp i en Bicep-fil kan du placera en discriminator dekoratör ovanför en användardefinierad typdeklaration. Bicep CLI version 0.21.X eller senare krävs för att använda den här dekoratören. I följande exempel visas hur du deklarerar en taggad unionsdatatyp:

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

Mer information finns i Anpassad taggad union-datatyp.

Importera typer mellan Bicep-filer

Endast användardefinierade datatyper som bär dekoratören @export() kan importeras till andra mallar.

I följande exempel kan du importera de två användardefinierade datatyperna från andra mallar:

@export()
type myStringType = string

@export()
type myOtherStringType = myStringType

Mer information finns i Importera användardefinierade datatyper.

Nästa steg

  • En lista över Bicep-datatyperna finns i Datatyper.