Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Difference between Readonly<[]> and ReadOnlyArray<>

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?

like image 357
Ramesh Rajendran Avatar asked Jan 17 '18 12:01

Ramesh Rajendran


People also ask

What is ReadonlyArray in TypeScript?

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.

What is readonly array?

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.

What is diff between const and read-only properties in TypeScript?

Summary: they are the same but const is for variables & readonly is for class properties.

What is the difference between constant and readonly in JavaScript?

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.


2 Answers

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 
like image 126
Titian Cernicova-Dragomir Avatar answered Nov 08 '22 12:11

Titian Cernicova-Dragomir


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
    
like image 21
Aravind Avatar answered Nov 08 '22 11:11

Aravind