First, be sure you update to Quest 5.4.1, as I think the template issue when using [] got fixed. (Though this might be another case.)
Second, Quest doesn't support arrays as such. There are some "hacky" solutions, if you really need them, but the one to use depends on your needs.
Quest only supports lists, dictionaries and objects as compound structures. Let's take each one.
1) Lists are indexed by integers, so they're similar to arrays when reading. If you have a list named "arr" with 5 entries, then you can use either ListItem(arr, 2) or arr[2] (if you have 5.4.1) to access the third element (lists are 0-based). But lists can only be built sequentially. You don't have random setting - there's no way to change the value of the third element once it's been set. So if you have a read-only array that you set up once sequentially, then you can use a list and access the items via index.
To create: NewList()
To delete: <automatically cleaned up when no longer referenced>
Index type: int
To set: ListAdd. List items must be added sequentially or in static lists.
To get: ListItem or []
2) Dictionaries have the advantage that you can read and assign to them randomly (assuming you delete the old value first), but the indices are strings only. That's not too bad as you can always convert an int to a string via ToString. Also, since the string can be anything as long as its unique, you can also do multidimensional via creative index construction. For example, if you have a dictionary called "arr", you can use DictionaryItem(arr, "1,1,1") or arr["1,1,1"] (if you have Quest 5.4.1) to access that element. You need to build the strings from numbers, but you could easily wrap that up in functions to hide the int-to-string index conversion. I did that in that silly little Breakout demo I wrote long ago.
To create: NewDictionary()
To delete: <automatically cleaned up when no longer referenced>
Index type: string
To set: DictionaryAdd (possibly after DIctionaryRemove of old value).
To get: DictionaryItem or []
3) Objects are like dictionaries in that you can assign to them randomly and in that the indices are strings. Objects have the advantage that you don't have to remove an existing value before you set a new one. The disadvantages are that objects are trickier to dynamically allocate since they must be uniquely named, they must be explicitly freed, and you can't use the [] notation - you have to use get and set.
To create: create (possibly with GetUniqueElementName)
To delete: destroy
Index type: string
To set: set
To get: get
I should probably put together a simple array library.

You wouldn't be able to use the [] notation, but it could hide the index conversions inside.
I don't know if that helps, but that's my take on it.