在 Bicep 中使用者自訂資料類型

了解如何在 Bicep 中建立使用者定義的資料類型。 如需系統定義的資料類型,請參閱 資料類型。 使用使用者定義的資料類型會自動啟用語言版本 2.0 程式碼產生。

需要 Bicep CLI 0.12.X 版或更高版本才能使用此功能。

use-user-defined-types linter 規則會鼓勵使用 使用者自訂資料型別,而非通用的 object 或 array 型別。

定義類型

使用該 type 語句來建立使用者定義的資料型態。 您也可以在某些地方使用類型運算式來定義自訂類型。

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

只有 @allowed上才允許 param 裝飾項目。 若要在 type 中宣告具有一組預先定義值的類型,請使用等位類型語法。

有效的型態表達式包括:

象徵性參照

符號參考是用來參照 ambient 型別(例如 string 或 int)或在 type 陳述式中宣告之使用者定義型別符號的識別碼。

// Bicep data type reference
type myStringType = string

// user-defined type reference
type myOtherStringType = myStringType

基本常值

基本常值 (包括字串、整數和布林值) 都是有效的類型運算式。 例如:

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

陣列類型

你可以透過在任何有效的型態表達式後附加 [] 來宣告陣列型別。 例如:

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

聯合型別

聯集型別允許你建立由一組子型組成的組合型別。 若值與某個子類型相符,則該值與該類型相符。 使用管線(|)操作符來區分各個成員類型。 Bicep 將聯集型別轉換成允許值限制,因此只允許常值做為成員。 等位可能包含任意數目的常值型別運算式。

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

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

您可以在行內中宣告聯集型別,讓成員做為另一個常值型別符號的參考。

混合型別聯集

成員型別不需要一定為相同類型的常值。 聯集可以組合字串、整數、布林值、物件和null常值。

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

Note

此 | 運算元也用於本文其他部分所述的多個相關情境:

  • 若要建立一個元素限制為聯集成員的陣列,請參見 陣列類型。
  • 若要將 | 運算子與 @discriminator() 裝飾器配對並建立可區分聯集,請參閱 標記聯集資料類型。
  • 當你使用 Resource-derived 類型時,它們的擴展對應物會以聯集來表示。

物件類型

物件類型包含大括弧之間的零個或多個屬性:

type storageAccountConfigType = {
  name: string
  sku: string
}

物件中的每個屬性都包含索引鍵和值,並以冒號 : 分隔。 索引鍵可以是任何字串,並以引號括住非識別碼值。 值可以是任何類型的運算式。

除非屬性在屬性值之後有選擇性標記 ?,否則需要屬性。 例如,下列範例中的 sku 屬性是選擇性的:

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

您可以在屬性上使用裝飾項目。 您可以使用星號 (*),以讓所有值都需要限制式。 您可以使用 * 來定義更多屬性。 此範例會建立物件,而此物件需要名為 int 且類型為 id 的索引鍵。 物件中的所有其他項目都必須是長度至少為 10 個字元的字串值。

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

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

下列範例示範如何使用等位類型語法來列出一組預先定義的值:

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

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

遞迴

如果遞迴點的路徑至少有一段是選擇性的,則物件類型可以使用直接或間接遞迴。 例如,下列範例中的 myObjectType 定義有效,因為直接遞迴 recursiveProp 屬性是選擇性的:

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

以下型別定義無效,因為 level1、level2、level3、level4 或 level5 都不是可選的。

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

一元運算子

使用 Bicep 一元運算子搭配整數和布林常值或整數或布林常值型別符號的參考。

type negativeIntLiteral = -10
type negatedIntReference = -negativeIntLiteral

type negatedBoolLiteral = !true
type negatedBoolReference = !negatedBoolLiteral

等位可能包含任意數目的常值型別運算式。 Bicep 將聯集型別轉換成允許值限制,因此只允許字面值作為成員。

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

在 type 陳述式中使用型別表達式。 你也可以使用型別表達式來建立使用者自訂的資料型別,如下文所示。

  • 在 param 陳述式的型別子句中。 例如:

    param storageAccountConfig {
      name: string
      sku: string
    }
    
  • 在物件類型屬性中 : 之後。 例如:

    param storageAccountConfig {
    name: string
      properties: {
        sku: string
      }
    } = {
      name: 'store$(uniqueString(resourceGroup().id)))'
      properties: {
        sku: 'Standard_LRS'
      }
    }
    
  • 在陣語型別運算式的 [] 前面。 例如:

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

建立儲存體帳戶的一般 Bicep 檔案看起來如下:

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

使用使用者定義的資料類型時,其看起來如下:

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

使用裝飾項目

以該格式 @expression 撰寫裝飾器,並將其置於使用者定義資料型別的宣告上方。 下表顯示使用者定義的資料類型可用的裝飾項目。

裝飾項目 套用對象 論點 描述
描述 all 字串 提供使用者定義資料類型的描述。
鑒別器 物件 字串 使用此裝飾項目,確保會正確識別及管理子類別。
export all 沒有 表示使用者定義的資料類型可供其他 Bicep 檔案匯入。
maxLength 陣列、字串 整數 (int) 字串和陣列資料類型的最大長度。 此值為內含。
maxValue 整數 (int) 整數 (int) 整數資料類型的最大值。 此值為內含。
中繼資料 all 物件 要套用至資料類型的自訂屬性。 可以包含相當於描述裝飾項目的描述屬性。
minLength 陣列、字串 整數 (int) 字串和陣列資料類型的最小長度。 此值為內含。
minValue 整數 (int) 整數 (int) 整數資料類型的最小值。 此值為內含。
密封的 物件 沒有 當使用者定義資料類型的屬性名稱可能有拼字錯誤時,將 BCP089 從警告提升為錯誤。 如需詳細資訊,請參閱提升錯誤層級。
安全 字串、物件 沒有 將類型標示為安全。 安全類型的值不會儲存在部署歷程記錄中,且不會記錄。 如需詳細資訊,請參閱安全字串和物件。

裝飾項目在 sys 命名空間中。 如果您需要區別裝飾項目與具有相同名稱的另一個項目,請在裝飾項目前面加上 sys。 例如,如果您的 Bicep 檔案包括名為 description 的變數,則您必須在使用 sys 裝飾項目時新增 description 命名空間。

鑑別子

請參閱標記的等位資料類型。

描述

將描述新增至使用者定義的資料類型。 您可以在屬性上使用裝飾項目。 例如:

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

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

您可以將 Markdown 格式的文字用於描述文字。

出口

使用 @export() 與其他 Bicep 檔案共用使用者定義的資料類型。 如需詳細資訊,請參閱匯出變數、類型和函式。

整數限制式

為整數類型設定最小值與最大值。 您可以設定一或兩個限制式。

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

長度限制

指定字串與陣列型態的最小與最大長度。 您可以設定一或兩個限制式。 若為字串,長度代表字元數。 若為陣列,長度代表陣列中的項目數。

下列範例會宣告兩個類型。 一個類型用於必須有 3 到 24 個字元的儲存體帳戶名稱。 另一個類型是必須有一到五個項目的陣列。

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

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

中繼資料

如果您有自訂屬性要套用至使用者定義的資料類型,請新增中繼資料裝飾項目。 在中繼資料內,使用自訂名稱和值定義物件。 您為中繼資料定義的物件可以包含任何名稱和類型的屬性。

使用此裝飾器來追蹤不適合新增到描述的資料類型相關資訊。

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

當您為 @metadata() 裝飾器提供一個與另一個裝飾器衝突的屬性時,@metadata() 值中的衝突屬性屬於多餘,並會被取代。 如需詳細資訊,請參閱沒有衝突的中繼資料 (機器翻譯)。

密封

請參閱提升錯誤層級。

安全類型

您可以將字串或物件使用者定義資料類型標示為安全。 安全類型的值不會儲存在部署歷程記錄中,且不會記錄。

@secure()
type demoPassword string

@secure()
type demoSecretObject object

提升錯誤層級

根據預設,在 Bicep 中宣告物件類型可讓其接受任何類型的更多屬性。 例如,下列 Bicep 有效,但會引發警告 [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'
}

此警告會通知您:anObject 類型未包括名為 otionalProperty 的屬性。 雖然部署期間未發生錯誤,但 Bicep 編譯器會假設 otionalProperty 是錯字,而且您打算使用 optionalProperty 但拼錯。 Bicep 會向您發出不一致的警示。

若要將這些警告提升為錯誤,請將 @sealed() 裝飾項目套用至物件類型:

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

將 @sealed() 裝飾項目套用至 param 宣告,會取得相同的結果:

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

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

Azure Resource Manager 部署引擎也會檢查密封類型是否有其他屬性。 為密封參數提供任何額外屬性會導致驗證錯誤,進而導致部署失敗。 例如:

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

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

標記的等位資料類型

若要在 Bicep 檔案中宣告自訂標記等位資料類型,您可以將 discriminator 裝飾項目放在使用者定義類型宣告之上。 需要 Bicep CLI 0.21.X 版或更高版本才能使用此裝飾項目。 下列範例示會範如何宣告標記的等位資料類型:

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

如需詳細資訊,請參閱 自訂標記的等位資料類型。

資源衍生類型

Bicep 可讓您藉由使用 resourceInput<> 和 resourceOutput<> 建構,直接從 Azure 資源結構描述中衍生型別。 透過使用資源衍生型別,你可以將參數和變數與資源體的一部分對照,而不必使用自訂型別。 要使用這些結構,你需要 Bicep CLI 版本 0.34.1 或更高。

範本可以在預期類型時重複使用資源類型。

resourceInput<'type@version'>
  • resourceInput<>: 表示資源類型的可寫屬性,移除 ARM 範本結構中標記為 ReadOnly 的屬性。 它會使用您需要傳遞給資源宣告的類型。
resourceOutput<'type@version'>
  • resourceOutput<>: 表示資源類型的可讀屬性,移除 ARM 範本結構中標記為 WriteOnly 的屬性。 它符合布建完資源後傳回的值類型。

您可以套用 resourceInput<> 或 resourceOutput<> 只擷取資源架構的一部分。 例如,若要根據儲存帳戶中的 kind 或 properties 來輸入變數或參數:

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

上述範例相當於:

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

下列範例顯示如何使用 resourceInput<>,以根據儲存體帳戶資源的 properties 來建立類型參數。 此方法定義一個參數,與儲存帳號可寫屬性相符,如 accessTier、 minimumTlsVersion及其他屬性:

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

下列範例顯示如何使用 resourceOutput<>,以根據儲存體帳戶資源的 primaryEndPoints 來建立類型輸出。

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

與使用者定義的資料型別不同,Bicep 在編輯或編譯檔案時會檢查資源衍生型別,但 ARM 服務不會檢查這些類型。

若要 Bicep 資料類型的清單,請參閱資料類型。