Udostępnij za pośrednictwem


Typy danych zdefiniowane przez użytkownika w Bicep

Dowiedz się, jak tworzyć typy danych zdefiniowanych przez użytkownika w aplikacji Bicep. W przypadku typów danych zdefiniowanych przez system zobacz Typy danych. Użycie typów danych zdefiniowanych przez użytkownika automatycznie włącza generowanie kodu w wersji 2.0 .

Do korzystania z tej funkcji jest wymagany interfejs wiersza polecenia Bicep w wersji 0.12.X lub nowszej .

Definiowanie typów

Instrukcję type można użyć do tworzenia typów danych zdefiniowanych przez użytkownika. Możesz również użyć wyrażeń typu w niektórych miejscach do definiowania typów niestandardowych.

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

Dekorator @allowed jest dozwolony tylko na param instrukcjach. Aby zadeklarować typ z zestawem wstępnie zdefiniowanych wartości w obiekcie type, użyj składni typu unii.

Prawidłowe wyrażenia typów obejmują:

  • Odwołania symboliczne to identyfikatory odwołujące się do typu otoczenia (na przykład string lub int) lub symbolu typu zdefiniowanego przez użytkownika zadeklarowanego w instrukcji type :

    // Bicep data type reference
    type myStringType = string
    
    // user-defined type reference
    type myOtherStringType = myStringType
    
  • Literały pierwotne, w tym ciągi, liczby całkowite i wartości logiczne, są prawidłowymi wyrażeniami typów. Na przykład:

    // 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
    
  • Typy tablic można zadeklarować, dołączając [] do dowolnego prawidłowego wyrażenia typu:

    // 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)[]
    
  • Typy obiektów zawierają zero lub więcej właściwości między nawiasami klamrowymi:

    type storageAccountConfigType = {
      name: string
      sku: string
    }
    

    Każda właściwość obiektu składa się z klucza i wartości rozdzielonej dwukropkiem :. Klucz może być dowolnym ciągiem z wartościami nieidentyfikatora ujętymi w cudzysłów. Wartość może być dowolnym typem wyrażenia.

    Właściwości są wymagane, chyba że mają znacznik ? opcjonalności po wartości właściwości. Na przykład właściwość w poniższym przykładzie sku jest opcjonalna:

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

    Można użyć dekoratorów we właściwościach. Możesz użyć gwiazdki (*), aby wszystkie wartości wymagały ograniczenia. Więcej właściwości można zdefiniować przy użyciu polecenia *. W tym przykładzie tworzony jest obiekt, który wymaga klucza typu int o nazwie id. Wszystkie inne wpisy w obiekcie muszą być wartością ciągu co najmniej 10 znaków.

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

    W poniższym przykładzie pokazano, jak używać składni typu unii do wyświetlania listy wstępnie zdefiniowanych wartości:

    type directions = 'east' | 'south' | 'west' | 'north'
    
    type obj = {
      level: 'bronze' | 'silver' | 'gold'
    }
    
  • Typy obiektów mogą używać rekursji bezpośredniej lub pośredniej, jeśli co najmniej część ścieżki do punktu rekursji jest opcjonalna. Na przykład definicja w poniższym przykładzie jest prawidłowa, myObjectType ponieważ właściwość bezpośrednia rekursywna recursiveProp jest opcjonalna:

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

    Następująca definicja typu nie byłaby prawidłowa, ponieważ żadna z level1wartości , level2, level3, level4lub level5 nie jest opcjonalna.

    type invalidRecursiveObjectType = {
      level1: {
        level2: {
          level3: {
            level4: {
              level5: invalidRecursiveObjectType
            }
          }
        }
      }
    }
    
  • Można użyć operatorów jednoargumentowych Bicep z literałami całkowitymi i logicznymi lub odwołaniami do symboli typu całkowitoliczbowego lub logicznego:

    type negativeIntLiteral = -10
    type negatedIntReference = -negativeIntLiteral
    
    type negatedBoolLiteral = !true
    type negatedBoolReference = !negatedBoolLiteral
    
  • Związki mogą zawierać dowolną liczbę wyrażeń typowych literałów. Typy unii są tłumaczone na ograniczenie dozwolonej wartości w Bicep, więc tylko literały są dozwolone jako elementy członkowskie.

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

W instrukcji type można użyć wyrażeń typu, a także użyć wyrażeń typu do utworzenia typów danych zdefiniowanych przez użytkownika, jak pokazano w następujących miejscach:

  • Jako klauzula param type instrukcji. Na przykład:

    param storageAccountConfig {
      name: string
      sku: string
    }
    
  • : Po właściwości w typie obiektu. Na przykład:

    param storageAccountConfig {
     name: string
      properties: {
        sku: string
      }
    } = {
      name: 'store$(uniqueString(resourceGroup().id)))'
      properties: {
        sku: 'Standard_LRS'
      }
    }
    
  • Poprzedzając element [] w wyrażeniu typu tablicy. Na przykład:

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

Typowy plik Bicep do utworzenia konta magazynu wygląda następująco:

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

W przypadku typów danych zdefiniowanych przez użytkownika może to wyglądać następująco:

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

Korzystanie z dekoratorów

Dekoratory są zapisywane w formacie @expression i są umieszczane powyżej deklaracji typu danych zdefiniowanego przez użytkownika. W poniższej tabeli przedstawiono dostępne dekoratory dla typów danych zdefiniowanych przez użytkownika.

Dekorator Zastosuj do Argument opis
opis wszystkie string Podaj opisy typu danych zdefiniowanego przez użytkownika.
Rozróżniacza obiekt string Użyj tego dekoratora, aby upewnić się, że prawidłowa podklasa jest identyfikowana i zarządzana.
export wszystkie Brak Wskazuje, że typ danych zdefiniowany przez użytkownika jest dostępny do zaimportowania przez inny plik Bicep.
maxLength tablica, ciąg int Maksymalna długość typów danych ciągów i tablic. Wartość jest inkluzywna.
maxValue int int Maksymalna wartość dla typów danych całkowitych. Ta wartość jest inkluzywna.
metadane wszystkie obiekt Właściwości niestandardowe, które mają być stosowane do typów danych. Może zawierać właściwość opisu, która jest równoważna dekoratorowi opisu.
minLength tablica, ciąg int Minimalna długość typów danych ciągów i tablic. Wartość jest inkluzywna.
minValue int int Minimalna wartość dla typów danych całkowitych. Ta wartość jest inkluzywna.
sealed obiekt Brak Podnieś poziom BCP089 z ostrzeżenia do błędu, gdy nazwa właściwości typu danych zdefiniowanego przez użytkownika prawdopodobnie jest literówką. Aby uzyskać więcej informacji, zobacz Podnoszenie poziomu błędu.
zabezpieczyć ciąg, obiekt Brak Oznacza typy jako bezpieczne. Wartość typu bezpiecznego nie jest zapisywana w historii wdrożenia i nie jest rejestrowana. Aby uzyskać więcej informacji, zobacz Zabezpieczanie ciągów i obiektów.

Dekoratory znajdują się w przestrzeni nazw systemu. Jeśli musisz odróżnić dekorator od innego elementu o tej samej nazwie, należy poprzeć dekorator za pomocą polecenia sys. Jeśli na przykład plik Bicep zawiera zmienną o nazwie description, należy dodać sys przestrzeń nazw podczas korzystania z dekoratora description .

Rozróżniacza

Zobacz Tagowany typ danych unii.

opis

Dodaj opis do typu danych zdefiniowanego przez użytkownika. Można użyć dekoratorów we właściwościach. Na przykład:

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

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

Tekst opisu można użyć w formacie Markdown.

Export

Użyj @export() polecenia , aby udostępnić typ danych zdefiniowany przez użytkownika innym plikom Bicep. Aby uzyskać więcej informacji, zobacz Eksportowanie zmiennych, typów i funkcji.

Ograniczenia liczb całkowitych

Można ustawić wartości minimalne i maksymalne dla typu liczby całkowitej. Można ustawić jedno lub oba ograniczenia.

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

Ograniczenia długości

Można określić minimalną i maksymalną długość dla typów ciągów i tablic. Można ustawić jedno lub oba ograniczenia. W przypadku ciągów długość wskazuje liczbę znaków. W przypadku tablic długość wskazuje liczbę elementów w tablicy.

Poniższy przykład deklaruje dwa typy. Jednym typem jest nazwa konta magazynu, która musi mieć od 3 do 24 znaków. Innym typem jest tablica, która musi zawierać od jednego do pięciu elementów.

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

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

Metadane

Jeśli masz właściwości niestandardowe, które chcesz zastosować do typu danych zdefiniowanego przez użytkownika, dodaj dekorator metadanych. W metadanych zdefiniuj obiekt z niestandardowymi nazwami i wartościami. Obiekt zdefiniowany dla metadanych może zawierać właściwości dowolnej nazwy i typu.

Możesz użyć tego dekoratora do śledzenia informacji o typie danych, które nie mają sensu dodawać do opisu.

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

Po podaniu dekoratora @metadata() z właściwością, która powoduje konflikt z innym dekoratorem, dekorator zawsze ma pierwszeństwo przed wszystkimi elementami w dekoratorze @metadata() . Dlatego właściwość powodująca konflikt w ramach @metadata() wartości jest nadmiarowa i jest zastępowana. Aby uzyskać więcej informacji, zobacz Brak powodujących konflikt metadanych.

Zamknięte

Zobacz Podnoszenie poziomu błędu.

Typy zabezpieczeń

Możesz oznaczyć ciąg lub typ danych zdefiniowany przez użytkownika jako bezpieczny. Wartość bezpiecznego typu nie jest zapisywana w historii wdrożenia i nie jest rejestrowana.

@secure()
type demoPassword string

@secure()
type demoSecretObject object

Podnoszenie poziomu błędu

Domyślnie deklarowanie typu obiektu w Bicep umożliwia akceptowanie większej liczby właściwości dowolnego typu. Na przykład następujący Bicep jest prawidłowy, ale zgłasza ostrzeżenie [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'
}

Ostrzeżenie informuje o tym anObject , że typ nie zawiera właściwości o nazwie otionalProperty. Mimo że podczas wdrażania nie występują żadne błędy, kompilator Bicep zakłada, że otionalProperty jest to literówka i że zamierzasz go użyć optionalProperty , ale błędnie go wpisał. Bicep powiadamia o niespójności.

Aby eskalować te ostrzeżenia do błędów, zastosuj @sealed() dekorator do typu obiektu:

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

Te same wyniki można uzyskać, stosując @sealed() dekorator do deklaracji param :

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

Aparat wdrażania usługi Azure Resource Manager sprawdza również zapieczętowane typy pod kątem innych właściwości. Podanie dodatkowych właściwości dla zapieczętowanych parametrów powoduje błąd weryfikacji, co powoduje niepowodzenie wdrożenia. Na przykład:

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

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

Oznakowany typ danych unii

Aby zadeklarować niestandardowy otagowany typ danych unii w pliku Bicep, można umieścić discriminator dekorator powyżej deklaracji typu zdefiniowanego przez użytkownika. Do korzystania z tego dekoratora wymagany jest interfejs wiersza polecenia Bicep w wersji 0.21.X lub nowszej . W poniższym przykładzie pokazano, jak zadeklarować oznakowany typ danych unii:

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

Aby uzyskać więcej informacji, zobacz Niestandardowy otagowany typ danych unii.

Aby uzyskać listę typów danych Bicep, zobacz Typy danych.