Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Provide support for typed variables + Bicep doesn't validate the type of variables in a loop #11891

Open
dekomissMSFT opened this issue Sep 19, 2023 · 2 comments
Labels
enhancement New feature or request type system
Milestone

Comments

@dekomissMSFT
Copy link

Is your feature request related to a problem? Please describe.

I am using Bicep v0.21.1 and have enabled "compileTimeImports": true in my bicepconfig.json (though I don't think this is necessary to repro)

I have a Bicep module where I want to pass in an object and use that to create various resources. I defined a custom type for the object and added it as a parameter to the module. In a parent template, I define the object in a variable and pass it to the module. I would like for Bicep to show me where properties are missing in the variable rather than where I reference the variable.

Example

CosmosDbDatabaseWithContainers.module.bicep

@export()
type sqlDatabaseConfigurationType = {
  name: string
  containerConfigurations: containerConfigurationType[]
}

type containerConfigurationType = {
  name: string
  indexingPolicy: object
}

param cosmosDbAccountName string

param sqlDatabaseConfiguration sqlDatabaseConfigurationType

resource cosmosDbAccount 'Microsoft.DocumentDB/databaseAccounts@2020-04-01' existing = {
  name: cosmosDbAccountName
}

resource sqlDatabase 'Microsoft.DocumentDB/databaseAccounts/sqlDatabases@2020-03-01' = {
  parent: cosmosDbAccount
  name: sqlDatabaseConfiguration.name
  properties: {
    resource: {
      id: sqlDatabaseConfiguration.name
    }
  }
}

@batchSize(1)
resource containers 'Microsoft.DocumentDB/databaseAccounts/sqlDatabases/containers@2020-03-01' = [for container in sqlDatabaseConfiguration.containerConfigurations: {
  parent: sqlDatabase
  name: container.name
  properties: {
    resource: {
      id: container.name
      indexingPolicy: container.indexingPolicy
    }
  }
}]

CosmosDbAccount.bicep

import { sqlDatabaseConfigurationType } from 'CosmosDbDatabaseWithContainers.module.bicep'

var defaultIndexingPolicy = { /* omitted for brevity*/ }

var database1Configuration = {
  name: 'Database1'
  containerConfigurations: [
    {
      name: 'Collection1'
      indexngPolicy: defaultIndexingPolicy // typo in property
    }
    {
      name: 'Collection2' // missing a property
    }
  ]
}

var sqlDatabaseConfigurations = [
  database1Configuration
  /* other configs omitted */
]

resource cosmosDbAccount 'Microsoft.DocumentDB/databaseAccounts@2020-04-01' = {
  name: 'myaccount'
  location: 'eastus'
  properties: {
    databaseAccountOfferType: 'Standard'
    locations: [/* omitted */]
  }
}

module sqlDatabases 'CosmosDbDatabaseWithContainers.module.bicep' = [for database in sqlDatabaseConfigurations: {
  name: database.name
  params: {
    cosmosDbAccountName: 'myaccount'
    sqlDatabaseConfiguration: database1Configuration
  }
}]

Describe the solution you'd like

Problem 1:
The line at the end that reads "sqlDatabaseConfiguration: database1Configuration" shows an error indicating the typo and missing property:
image

It would be ideal to see these errors show up on the lines where the typo/missing property actually are within the variable, since for a large object that references other variables it could be difficult to spot where the issue is.

Problem 2:
If I change "sqlDatabaseConfiguration: database1Configuration" to "sqlDatabaseConfiguration: database" to use the value from the loop, then Bicep doesn't display any error at all. I would like to see the same error that I see in the above screenshot.

image

@jeskew
Copy link
Member

jeskew commented Sep 28, 2023

I agree with you that type hints on variables would improve the experience here. I think Bicep is doing the right thing by showing diagnostics on the variable reference rather than the variable definition, since variables may be used in multiple places. If Bicep gave you a way to provide a type for a variable, though, diagnostics would get attached to the declaration itself:

var database1Configuration: sqlDatabaseConfigurationType = {
  name: 'Database1'
  containerConfigurations: [
    {
      name: 'Collection1'
      indexngPolicy: defaultIndexingPolicy // this line would have a diagnostic since it doesn't match the declared type due to a property name typo
    }
    { // this line and the next two would have a diagnostic since it doesn't match the declared type due to a missing property
      name: 'Collection2'
    }
  ]
}

When using a loop, it looks like Bicep will fall back to an untyped object if the elements of an array can't be collapsed to a single type. This could certainly be improved: Bicep should be able to figure out that the loop-local database variable has a type of:

type loopLocal_database = {
  name: 'Collection1' | 'Collection2'
  indexngPolicy: <inferred type of defaultIndexingPolicy>?
}

@jeskew
Copy link
Member

jeskew commented Sep 28, 2023

@dekomissMSFT would you mind upvoting #9364 for typed variable support? We can use this issue to track the loop-local variable type inference gap.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
enhancement New feature or request type system
Projects
Status: Todo
Development

No branches or pull requests

5 participants