Skip to content

Commit 90be1cd

Browse files
Merge pull request #284862 from mumian/0814-sealed
Document sealed() decorator
2 parents ef019a1 + 9ecfb35 commit 90be1cd

File tree

1 file changed

+66
-9
lines changed

1 file changed

+66
-9
lines changed

articles/azure-resource-manager/bicep/user-defined-data-types.md

Lines changed: 66 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -3,24 +3,24 @@ title: User-defined types in Bicep
33
description: Describes how to define and use user-defined data types in Bicep.
44
ms.topic: conceptual
55
ms.custom: devx-track-bicep
6-
ms.date: 06/14/2024
6+
ms.date: 08/16/2024
77
---
88

99
# User-defined data types in Bicep
1010

11-
Learn how to use user-defined data types in Bicep. For system-defined data types, see [Data types](./data-types.md).
11+
Learn how to create user-defined data types in Bicep. For system-defined data types, see [Data types](./data-types.md).
1212

1313
[Bicep CLI version 0.12.X or higher](./install.md) is required to use this feature.
1414

1515
## Syntax
1616

17-
You can use the `type` statement to define user-defined data types. In addition, you can also use type expressions in some places to define custom types.
17+
You can use the `type` statement to create user-defined data types. In addition, you can also use type expressions in some places to define custom types.
1818

1919
```bicep
2020
type <user-defined-data-type-name> = <type-expression>
2121
```
2222

23-
The [`@allowed`](./parameters.md#decorators) decorator is only permitted on [`param` statements](./parameters.md). To declare that a property with a set of predefined values in a `type`, use [union type syntax](./data-types.md#union-types).
23+
The [`@allowed`](./parameters.md#decorators) decorator is only permitted on [`param` statements](./parameters.md). To declare a type with a set of predefined values in a `type`, use [union type syntax](./data-types.md#union-types).
2424

2525
The valid type expressions include:
2626

@@ -47,7 +47,7 @@ The valid type expressions include:
4747
type myBoolLiteralType = true
4848
```
4949
50-
- Array types can be declared by suffixing `[]` to any valid type expression:
50+
- You can declare array types by appending `[]` to any valid type expression:
5151
5252
```bicep
5353
// A string type array
@@ -70,7 +70,7 @@ The valid type expressions include:
7070
}
7171
```
7272
73-
Each property in an object consists of key and value. The key and value are separated by a colon `:`. The key may be any string (values that wouldn't be a valid identifier must be enclosed in quotes), and the value may be any type syntax expression.
73+
Each property in an object consists of a key and a value, separated by a colon `:`. The key can be any string, with nonidentifier values enclosed in quotes, and the value can be any type of expression.
7474
7575
Properties are required unless they have an optionality marker `?` after the property value. For example, the `sku` property in the following example is optional:
7676
@@ -81,7 +81,7 @@ The valid type expressions include:
8181
}
8282
```
8383
84-
Decorators may be used on properties. `*` may be used to make all values require a constraint. Additional properties may still be defined when using `*`. This example creates an object that requires a key of type int named `id`, and that all other entries in the object must be a string value at least 10 characters long.
84+
Decorators can be used on properties. `*` can be used to make all values require a constraint. Additional properties can still be defined when using `*`. This example creates an object that requires a key of type `int` named _id_, and that all other entries in the object must be a string value at least 10 characters long.
8585
8686
```bicep
8787
type obj = {
@@ -106,7 +106,7 @@ The valid type expressions include:
106106
107107
**Recursion**
108108
109-
Object types may use direct or indirect recursion so long as at least leg of the path to the recursion point is optional. For example, the `myObjectType` definition in the following example is valid because the directly recursive `recursiveProp` property is optional:
109+
Object types can use direct or indirect recursion so long as at least leg of the path to the recursion point is optional. For example, the `myObjectType` definition in the following example is valid because the directly recursive `recursiveProp` property is optional:
110110
111111
```bicep
112112
type myObjectType = {
@@ -141,7 +141,7 @@ The valid type expressions include:
141141
type negatedBoolReference = !negatedBoolLiteral
142142
```
143143
144-
- Unions may include any number of literal-typed expressions. Union types are translated into the [allowed-value constraint](./parameters.md#decorators) in Bicep, so only literals are permitted as members.
144+
- Unions can include any number of literal-typed expressions. Union types are translated into the [allowed-value constraint](./parameters.md#decorators) in Bicep, so only literals are permitted as members.
145145
146146
```bicep
147147
type oneOfSeveralObjects = {foo: 'bar'} | {fizz: 'buzz'} | {snap: 'crackle'}
@@ -227,6 +227,63 @@ resource storageAccount 'Microsoft.Storage/storageAccounts@2023-04-01' = {
227227
}
228228
```
229229

230+
## Elevate error level
231+
232+
By default, declaring an object type in Bicep allows it to accept additional properties of any type. For example, the following Bicep is valid but raises a warning of [BCP089] - `The property "otionalProperty" is not allowed on objects of type "{ property: string, optionalProperty: null | string }". Did you mean "optionalProperty"?`:
233+
234+
```bicep
235+
type anObject = {
236+
property: string
237+
optionalProperty: string?
238+
}
239+
240+
param aParameter anObject = {
241+
property: 'value'
242+
otionalProperty: 'value'
243+
}
244+
```
245+
246+
The warning informs you that the _anObject_ type doesn't include a property named _otionalProperty_. While no errors occur during deployment, the Bicep compiler assumes _otionalProperty_ is a typo, that you intended to use _optionalProperty_ but misspelled it, and alert you to the inconsistency.
247+
248+
To escalate these warnings to errors, apply the `@sealed()` decorator to the object type:
249+
250+
```bicep
251+
@sealed()
252+
type anObject = {
253+
property: string
254+
optionalProperty?: string
255+
}
256+
```
257+
258+
You get the same results by applying the `@sealed()` decorator to the `param` declaration:
259+
260+
```bicep
261+
type anObject = {
262+
property: string
263+
optionalProperty: string?
264+
}
265+
266+
@sealed()
267+
param aParameter anObject = {
268+
property: 'value'
269+
otionalProperty: 'value'
270+
}
271+
```
272+
273+
The ARM deployment engine also checks sealed types for additional properties. Providing any extra properties for sealed parameters results in a validation error, causing the deployment to fail. For example:
274+
275+
```bicep
276+
@sealed()
277+
type anObject = {
278+
property: string
279+
}
280+
281+
param aParameter anObject = {
282+
property: 'value'
283+
optionalProperty: 'value'
284+
}
285+
```
286+
230287
## Tagged union data type
231288

232289
To declare a custom tagged union data type within a Bicep file, you can place a `discriminator` decorator above a user-defined type declaration. [Bicep CLI version 0.21.X or higher](./install.md) is required to use this decorator. The following example shows how to declare a tagged union data type:

0 commit comments

Comments
 (0)