Why does a list type when fetched using agent.js turn into a nested array instead of a regular array?

I have a Motoko type that looks like this

The corresponding TypeScript types generated for this looks like this

Notice the types generated for the Motoko List types. They are nested types. So, when I get the result of any of those fields, they are nested as many layers as there are elements returned.

Looks like this:

This makes no sense intuitively. Why doesn’t a List return a plain JavaScript array instead of this nested mess?

1 Like

Lists are functional in their construction so each object points to the next one in the list. User toArray(List<T) when returning your function and you will get a uniform array.


Ie the list is built by adding each new element to an existing list:
(3 . (2 . (1 . null)))

1 Like

Right, so they behave like traditional linked lists.

Wondering if agent-js should parse this into a linear array instead of a nested one. Otherwise this is left up to the programmer to implement.

Reason I’m reluctant to do the array conversion on the canister side is that it’s extra work for the canister on every call vs just returning the data

Maybe converting the List to an Array on the canister side might result in fewer cycles spent overall, if the list is small enough? For example, my guess is that it’s probably more computationally expensive to serialize a List to Candid than an Array. No idea, just a guess…