I would like to know what are the factors that determine that an array of type T
can be cast to some tuple type such as: [T]
, [T,T]
, [T,T,T]
etc..
For simplicity let’s just take number arrays and some number vector type defined as
type V3 = readonly [number, number, number]
.
Note the type is readonly, as this was from my use case, but is as far as I can tell an important factor.
If I have some readonly number array:
type V3 = readonly [number, number, number];
const arr: readonly number[] = [1, 2, 3];
(arr as V3); // OK
The assertion is allowed. If we however have a mutable array, as you might get as soon as you perform some array functions e.g: arr.map((x) => x * 2)
, then:
type V3 = readonly [number, number, number];
const mutArr: number[] = [1, 2, 3];
mutArr as V3; // not OK
This is not allowed, with the following error: Target requires 3 element(s) but source may have fewer.
And if we had some mutable V3 type, and try to cast the mutable array to that, e.g:
type MutV3 = [number, number, number];
mutArr as MutV3; // OK
Then it’s allowed.
Here’s a link to a typescript playground with the examples.
So, concisely, my questions would be:
-
What, precisely, is stopping the assertion. From the examples I would have assumed the incompatibility is between the readonly and non readonly nature of the types. But the error message is focused on the length of arrays. As opposed to the: Not assignable to readonly property, error.
-
In a situation where you eventually have a mutable array you would like to cast to a readonly tuple, is the simplest way to cast to unknown first and then to tuple.
2