Azure / bicep

Bicep is a declarative language for describing and deploying Azure resources
MIT License
3.22k stars 746 forks source link

Can't use conditional statement for resource(serviceBus/namespaces/queues) parameters #14059

Closed marcincakA closed 4 months ago

marcincakA commented 4 months ago

Bicep version 0.27.1

Describe the bug Can't use conditional statement for resource(serviceBus/namespaces/queues) parameters (Error BCP053: The type "object" does not contain property "sessions". Available properties include "name".)

To Reproduce See provided file

Additional context This type of condition [line 37 -> contains(queue, 'sessions') ? queue.sessions : false] works fine when used for parameter of bicep module mainArrayIssue.zip

Image of the code image

miqm commented 4 months ago

I have similar problem but with sort function, here's a repro:

var items = [
  { obj: 1 }
  { obj: 2 }
  { obj: 3 }
  { obj: 4 }
  { obj: 5
    x: 5
  }
]
var s = sort(filter(map(items, x => x.obj < 2 ? { order: 1, value: x } : x.obj > 4 ? { order:2, value: x} : {}), x => !(empty(x))), (arg1, arg2) => arg1.order < arg2.order)

This was working in 0.26.70, so I think this is a bug in 0.27.1

The error I get is Argument of type "((object | object | object), (object | object | object)) => error" is not assignable to parameter of type "(any, any) => bool".bicep(BCP070)

marcincakA commented 4 months ago

Here is another issue that may be related image

Error message Error BCP052: The type "object" does not contain property "Value"

Here the error stems from the condition used inside the array variable (line 13) image

Without the condition it works mainConditionInArray.zip 114-9970-1db4fd2f5cfe)

anthony-c-martin commented 4 months ago

In both cases, I believe the issue is that type validation isn't smart enough to figure out that you're excluding the base case with the check for empty()

@miqm not the most elegant solution, but a temporary workaround could be to wrap with any():

var items = [
  { obj: 1 }
  { obj: 2 }
  { obj: 3 }
  { obj: 4 }
  { obj: 5, x: 5 }
]
var s = sort(
  filter(
    map(items, x => x.obj < 2 ? { order: 1, value: x } : x.obj > 4 ? { order: 2, value: x } : {}),
    x => !(empty(x))
  ),
  any((arg1, arg2) => arg1.order < arg2.order)
)

@marcincakA a workaround for your scenarios would be to use the .? operator:

queue.?sessions ?? false

miqm commented 4 months ago

yeah, I managed to find place to put any. anyway, would be good to not to have it.

miqm commented 4 months ago

In both cases, I believe the issue is that type validation isn't smart enough to figure out that you're excluding the base case with the check for empty()

Partially that's true, but even if remove filter and put a question mark on the order property, bicep still complains: image

anthony-c-martin commented 4 months ago

Ah I think I see the problem - I believe introduced with #14017.

Here's a minimal repro:

param foo string
param index int

var test = [
  { foo: foo }
  { }
][index]

output val string = test.foo
anthony-c-martin commented 4 months ago

@marcincakA if you get a chance, please could you verify whether #14060 fixes the problem for you?

This comment gives instructions on how to do this:

image