Assigned types should be control-flow sensitive
Is your feature request related to a problem? Please describe.
Within a ternary expression, Bicep can sometimes generate spurious diagnostics when a subexpression within the true or false clause interacts with a symbol that should be safe given the check in the if clause of the ternary.
For example, the following snippet:
var db = {
name: 'db1'
}
resource postgreSQL 'Microsoft.DBForPostgreSQL/servers@2017-12-01' existing = {
name: 'name'
resource database 'database' = {
name: db.name
properties: {
charset: contains(db, 'charset') ? db.charset : 'utf8'
collation: contains(db, 'collation') ? db.collation : 'English_United States.1252'
}
}
}
will generate the following diagnostics:
[BCP053 (Error)] The type "object" does not contain property "charset". Available properties include "name".
[BCP053 (Error)] The type "object" does not contain property "collation". Available properties include "name".
Describe the solution you'd like
Similar to how C# will recognize that foo is non-null inside of a block that starts with if (foo is not null) {, the Bicep compiler's type inference should take an expression's position in control flow into account when assigning a type to an expression. Given that Bicep does not have guard statements that control entry into blocks, this should primarily impact ternary statements. If possible, flow-sensitive typing should take into account:
- equality operators
- comparison operators, and
- some core functions in the
sysnamespace (e.g.,empty,length,contains,endsWith,startsWith, and negations thereof).
Related to #3750 (3rd option)
As suggested in #3750, the following should now be a viable workaround:
var db = {
name: 'db1'
}
resource postgreSQL 'Microsoft.DBForPostgreSQL/servers@2017-12-01' existing = {
name: 'name'
resource database 'database' = {
name: db.name
properties: {
charset: db.?charset ?? 'utf8'
collation: db.?collation ?? 'English_United States.1252'
}
}
}