Code 1:
let readonlyArray: ReadonlyArray<string | number> = ["test", 1, 1];
Code 2:
let readonlyArray: Readonly<[string, number]> = ["test", 1, 1];
Both lines of code seem to do similar things. I don't know what is the difference between declaring array as ReadOnly
and ReadOnlyArray
.
Also, which one is best for performance and why?
We can declare a typed tuple in TypeScript, for example, with the type annotation [string, number] . This means an array of 2 elements where the first element needs to be a string and the second a number. We can also declare read-only arrays with ReadonlyArray<string> which means a read-only array of strings.
A new syntax for ReadonlyArray The ReadonlyArray type describes Array s that can only be read from. Any variable with a reference to a ReadonlyArray can't add, remove, or replace any elements of the array. function foo(arr: ReadonlyArray<string>) { arr.
Summary: they are the same but const is for variables & readonly is for class properties.
Constants are immutable values which are known at compile time and do not change their values for the life of the program. Readonly variables are also immutable values which are known at run time and do not change their values for the life of the program.
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<T>
is not necessarily an array; that expects any type <T>
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
accepts by default an array Contains mutable methods
let readonlyArray: ReadonlyArray<string| number> = "test"; // not assignable
let readonlyArray: ReadonlyArray<string| number> = ["test"]; // assignable
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With