I am fairly new to strong typing but have been working in TypeScript for a little while now. I am starting to work through the Type Challenges to get better at strong typing and having a strong intuition about the type system in TypeScript.
Currently, I am wondering about the difference between these two options for declaring a type:
type TupleOptions = Array<number | string>;
type TupleOptions = (number | string)[];
My understanding is that they should be equivalent. However, I am working on 11 - Tuple to Object and seeing a difference when trying to use them.
// this works
type TupleToObject<T extends readonly (number | string)[]> = {
[key in T[number]]: key;
}
// this does NOT work
type TupleToObject<T extends readonly Array<number | string>> = {
[key in T[number]]: key;
}
I'm still new so this very much confuses me.
...And, beyond that issue I am interested to learn why - for this challenge - using any[] (errors) and (number | string)[] (passes) produces different results for the final test in the challenge:
// @ts-expect-error
type error = TupleToObject<[[1, 2], {}]>
Direct link to TypeScript Playground
Array<T>andT[]are equivalent. However, there's one special piece of syntax sugar that only works on the latter. Specifically,readonly T[]translates toReadOnlyArray<T>. So you should regardreadonly T[]as a sort of special syntax entirely distinct fromT[]; the only reason it's in the language at all is that people don't like writing out a long name likeArray<T>for a common type like arrays.