Difference between Readonly<[]> and ReadOnlyArray<>
From a performance point of view there should not be any difference between the two, as at runtime types are erase and the same javascript will run regardless
There is a fundamental difference between the two type at compile time:
Readonly<T>
- Is a type that has the same shape as T
but all the properties are read-only. In your case the T
is the tuple type [string, number]
, so it will have all the properties of array as well as the indexes 0 and 1. So we can call the push
method, but we can't reassign the concat
method.
let readonlyArray: Readonly<[string, number]> = ["test", 1, 1];
readonlyArray.concat = ()=> {} // Not valid, concat is readonly
readonlyArray.push(1); // This is valid
readonlyArray[1] = ""; // Invalid we cannot change a property by indexing
readonlyArray[3] = ""; // Valid as it was not in the original tuple type
Edit: Since 3.4, typescript has changed the behavior of mapped types on array and tuples, so Readonly<[string, number]>
is now equivalent to a readonly tuple readonly [string, number]
, so the errors are a bit different:
let readonlyArray: Readonly<[string, number]> = ["test", 1];
readonlyArray.concat = ()=> {} // Not valid, concat is readonly
readonlyArray.push(1); // This is not invalid, no push method anymore
readonlyArray[1] = ""; // Invalid we cannot change a property by indexing
readonlyArray[3] = ""; // Invalid now tuple length preserved
</Edit>
ReadonlyArray<T>
is a true readonly array that does not have any methods that can change the array. In your case any item of the array can be either a string
or a number
:
let readonlyArray2: ReadonlyArray<string | number> = ["test", 1, 1];
readonlyArray2.concat = ()=> []; // Valid we can set the concat property on the object
readonlyArray2.push(1) // No push method, invalid
readonlyArray2[1] = ""; // Invalid it is read only
readonlyArray2[3] = ""; // Invalid it is read only
Readonly
- The
Readonly<T>
is not necessarily an array; that expects any type<T>
- To make the
Readonly
to store an array of values, the type<T>
should be an[T]
Does not contain mutable methods
let readonlyArray: Readonly<string| number> = ["test", 1, 1]; // not assignable let readonlyArray: Readonly<[string| number]> = ["test", 1, 1]; // assignable
ReadonlyArray
- The
ReadonlyArray
accepts by default an array Contains mutable methods
let readonlyArray: ReadonlyArray<string| number> = "test"; // not assignable let readonlyArray: ReadonlyArray<string| number> = ["test"]; // assignable