Share via


Types de données définis par l’utilisateur dans Bicep

Découvrez comment exploiter des types de données définis par l’utilisateur dans Bicep.

Bicep CLI version 0.12.X ou ultérieure est nécessaire pour utiliser cette fonctionnalité.

Syntaxe du type de données défini par l'utilisateur

Vous pouvez employer l’instruction type pour définir les types de données définis par l’utilisateur. Vous pouvez également utiliser des expressions type à certains endroits pour définir des types personnalisés.

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

Remarque

Le @allowed décorateur n’est autorisé que sur les instructions param. Pour déclarer qu’une propriété doit être un ensemble de valeurs prédéfinies dans une type ou une instruction output, utilisez la syntaxe de type union. La syntaxe de type Union peut également être utilisée dans les instructions param.

Les expressions type valides sont les suivantes :

  • Les références symboliques sont des identificateurs qui font référence à un type ambiant (comme string ou int) ou à un symbole type défini par l’utilisateur déclaré dans une instruction type :

    // Bicep data type reference
    type myStringType = string
    
    // user-defined type reference
    type myOtherStringType = myStringType
    
  • Les littéraux primitifs, dont les chaînes, les entiers et les booléens, sont des expressions type valides. Par exemple :

    // 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
    
  • Les types de tableaux peuvent être déclarés en suffixe [] à n’importe quelle expression type valide :

    // 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)[]
    
  • Les types d’objets contiennent zéro ou plusieurs propriétés entre crochets bouclés :

    type storageAccountConfigType = {
      name: string
      sku: string
    }
    

    Chaque propriété d’un objet se compose d’une clé et d’une valeur. La clé et la valeur sont séparées par deux-points (:). La clé peut être n’importe quelle chaîne (les valeurs n’étant pas un identificateur valide doivent être placées entre guillemets) et la valeur peut être tout type d'expression syntaxique.

    Les propriétés sont requises, sauf si elles ont un marqueur d'option ? après la valeur de propriété. Par exemple, la propriété sku dans l’exemple suivant est facultative :

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

    Des éléments décoratifs peuvent être utilisés sur les propriétés. * peut être utilisé pour que toutes les valeurs nécessitent une contrainte. Des propriétés supplémentaires peuvent toujours être définies lors de l’utilisation de *. Cet exemple crée un objet nécessitant une clé de type int nommée id ; ainsi toutes les autres entrées de l’objet doivent être une valeur de chaîne d’au moins 10 caractères.

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

    L’exemple suivant montre comment utiliser la syntaxe de type union pour répertorier un ensemble de valeurs prédéfinies :

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

    Récursivité

    Les types d’objets peuvent utiliser une récursivité directe ou indirecte, tant qu’au moins la partie du chemin d’accès au point de récursivité est facultative. Par exemple, la définition myObjectType dans l’exemple suivant est valide, car la propriété directement récursive recursiveProp est facultative :

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

    Mais la définition de type suivante n’est pas valide, car aucune de level1, level2, , level3level4ou level5 n’est facultative.

    type invalidRecursiveObjectType = {
      level1: {
        level2: {
          level3: {
            level4: {
              level5: invalidRecursiveObjectType
            }
          }
        }
      }
    }
    
  • Les opérateurs unaires Bicep peuvent être employés avec des littéraux entiers et booléens ou des références à des symboles entiers ou de type littéral booléen :

    type negativeIntLiteral = -10
    type negatedIntReference = -negativeIntLiteral
    
    type negatedBoolLiteral = !true
    type negatedBoolReference = !negatedBoolLiteral
    
  • Les unions peuvent comporter n’importe quel nombre d’expressions type littérales. Les types union étant traduits en contrainte de valeur autorisée dans Bicep, seuls les littéraux sont autorisés comme membres.

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

En plus d’être utilisées dans l’instruction type, les expressions de type peuvent également être utilisées à ces emplacements pour créer des types de dates définis par l’utilisateur :

  • Comme clause type d’une param instruction. Par exemple :

    param storageAccountConfig {
      name: string
      sku: string
    }
    
  • Suivant le : dans une propriété type d’objet. Par exemple :

    param storageAccountConfig {
     name: string
      properties: {
        sku: string
      }
    } = {
      name: 'store$(uniqueString(resourceGroup().id)))'
      properties: {
        sku: 'Standard_LRS'
      }
    }
    
  • Précédant le [] dans une expression type tableau. Par exemple :

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

Un fichier Bicep classique pour la création d’un compte de stockage ressemble à ceci :

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

En employant des types de données définis par l’utilisateur, il peut se présenter comme suit :

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

Déclarer un type d’union étiqueté

Pour déclarer un type de données d’union étiqueté personnalisé dans un fichier Bicep, vous pouvez placer un élément décoratif discriminant au-dessus d’une déclaration de type défini par l’utilisateur. Bicep CLI version 0.21.X ou ultérieure est nécessaire pour utiliser cet élément décoratif. La syntaxe est :

@discriminator('<propertyName>')

L’élément décoratif discriminant prend un seul paramètre, qui représente un nom de propriété partagée parmi tous les membres de l’union. Ce nom de propriété doit être un littéral de chaîne obligatoire sur tous les membres et respecte la casse. Les valeurs de la propriété discriminée sur les membres de l’union doivent être uniques d’une manière ne respectant pas la casse.

L’exemple suivant montre comment déclarer un type d’union étiqueté :

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

La valeur du paramètre est validée en fonction de la valeur de propriété discriminée. Dans l’exemple précédent, si la valeur du paramètre serviceConfig est de type foo, elle est soumise à une validation à l’aide du type FooConfig. De même, si la valeur du paramètre est de type bar, la validation est effectuée à l’aide du type BarConfig, et ce modèle continue également pour les autres types.

Importer des types entre des fichiers Bicep (préversion)

Bicep CLI version 0.21.X ou ultérieure est nécessaire pour utiliser cette fonctionnalité d’importation au moment de la compilation. Le drapeau expérimental compileTimeImports doit être activé à partir du fichier de configuration Bicep.

Seuls les types de données définis par l'utilisateur et portant le décorateur @export() peuvent être importés dans d'autres modèles. Actuellement, ce décorateur ne peut être utilisé que sur les relevés type.

L'exemple suivant vous permet d'importer les deux types de données définis par l'utilisateur à partir d'autres modèles :

@export()
type myStringType = string

@export()
type myOtherStringType = myStringType

Pour plus d'informations, consultez Importer des types de données définis par l'utilisateur.

Étapes suivantes