#hcl-types-and-coercion
What types does HCL have? What gets coerced implicitly and what doesn't?
Что отвечать
Primitives: string, number, bool. Collections: list(T), set(T), map(T), tuple([T1,T2,...]), object({k1=T1, k2=T2}). Plus null. Coercion goes one way. A number becomes a string in interpolation (`"port=${var.port}"`), a bool becomes the string `"true"`. The other direction does not happen by itself: to turn the string `"5"` into a number you call `tonumber()`. list and tuple are not the same: a list needs one shared T, a tuple has a fixed length with a different T per position. A set drops ordering and duplicates.
Что хотят услышать
The candidate should: - not mix up list and set: a set is handy for `for_each`, but its order is not guaranteed. A list keeps order, and it keeps duplicates - know the explicit converters `tostring`, `tonumber`, `tobool`, `tolist`, `toset`, `tomap` - explain object vs map: map(string) requires one value type, object allows a different type per key - say that a type constraint on a variable is a shape, not a strict type. `optional()` lets a field be missing from an object (since 1.3+)
Подводные камни
- ✗ Declaring `variable foo { type = list }` with no parameter: it accepts anything, with no checking. Always write `list(string)`
- ✗ Comparing `[1,2,3]` with `tolist([1,2,3])`: the first is a tuple, the second a list, the types differ, so `==` treats them as not equal
- ✗ Using `for_each` with a list: old versions failed, newer ones make you wrap it in `toset()`. Reach for a set from the start
Follow-up
- ? How does `object({})` differ from `map(any)` in a variable?
- ? What does `toset([1,1,2])` return?
- ? When do you need `optional()` in an object type?
Глубина в базе знаний