Array<string> vs. string[]

#learning #typescript

31st of August 2021

I’ve been using Array<string> format from the start and since my covorkers use it, I rarely encounter the other possibility. But this week there was a TypeScript related question posed on a local developer’s FaceBook group and all other answers used string[] structure.

Until now, I didn’t really question it, but I got curious. What are benefits of each? Are they the same?

No shocker, they are basically the same, this won’t be terribly interesting. But along the way I found couple of cool new stuff that I learned and I wanted to take a longer look. Hence, this.

To specify the type of an array like [1, 2, 3], you can use the syntax number[]; this syntax works for any type (e.g. string[] is an array of strings, and so on). You may also see this written as Array<number>, which means the same thing.

Ok that was fast. It’s the same. So string[] is a shorthand for Array<string> and both can be used, since they are the same. But are their uses the same? I found a comment about TypeScript v3.2 that introduced changes to readonly type modifier, expanding it to arrays and tuples. It is only permitted on array and tuple literal types and does not work on both syntaxes:

let err1: readonly Set<number>; // ERROR
let err2: readonly Array<boolean>; // ERROR

let ok: readonly boolean[]; // OK

But this does not mean that we can’t have consistency on our projects, if we are usin Array<> syntax, we just need to use the new ReadonlyArray<> syntax. It descibes an array that we can only read from, so any variable with it’s referene can’t add, remove, or replace any elements in the array.

This is my first time encountering a readonly modifier in TS. It seems neat. Why wouldn’t I be able to set some variable to some value and prevent it’s change. But then another question popped up. What is the difference between assigning a readonly and using a const?

One fun thing happens with arrays.

const SimpleArray: Array<number> = [1, 2, 3];

SimpleArray[0] = 2; // OK
SimpleArray.push(4); // OK
SimpleArray.pop(); // OK

SimpleArray = [4, 5, 6]; // ERROR

let AnotherSimpleArray: ReadonlyArray<number> = [1, 2, 3];

AnotherSimpleArray[0] = 2; //ERROR
AnotherSimpleArray.push(4); //ERROR
AnotherSimpleArray.pop(); //ERROR

AnotherSimpleArray = [4, 5, 6]; //OK

But the main use for readonly would be in interfaces and classes, where setting something to readonly does not mean that the value cannot be changed, but that it cannot be reassigned.