Overview
TypeScript 3.4 added a bit of syntactic sugar to the language that makes it easier to work with read-only array and tuple types. We can now use the readonly
modifier to create read-only array types (such as readonly string[]
) or read-only tuple types (such as readonly [number, number]
).
Read-Only Array Types in TypeScript
Let’s assume we’ve defined the following intersperse
function:
|
|
The intersperse
function accepts an array of elements of some type T
and a separator value of the same type T
. It returns a new array of elements with the separator value interspersed { 在……中夹杂某物 } in between each of the elements. In a way, the intersperse
function is similar to the Array.prototype.join()
method, except that it returns an array of the same type instead of a string.
Here are some usage examples of our intersperse
function:
|
|
Let’s now create an array that is annotated to be of type ReadonlyArray<string>
, a read-only array type:
|
|
This means that we don’t intend for this array to be mutated. TypeScript’s type checker will produce an error if we try to write to the array or call mutating array methods such as push()
, pop()
, or splice()
:
|
|
Alternatively, we could’ve used the new readonly
modifier to type our values
array as a read-only array:
|
|
ReadonlyArray<string>
and readonly string[]
represent the same type; you can pick whichever syntax you prefer. I like readonly T[]
because it’s more concise and closer to T[]
, but your mileage { 英里数;益处 } may vary. It’s just a matter of preference.
What happens if we now try to pass values
to intersperse
?
|
|
TypeScript gives us another type error!
|
|
The type checker points out that the read-only array type readonly string[]
cannot be assigned to the mutable array type string[]
. Here, the potential problem is that our intersperse
function could call mutating { 违反,违背 } methods on the array
parameter. That would violate the intended read-only behavior of the values
array.
We can make the type error go away by typing the array
parameter as a read-only array. By doing that, we’re indicating that our intersperse
function is not going to mutate the array
array:
|
|
If you’re writing a pure function that accepts an array as a parameter, I would recommend that you annotate that array parameter to be read-only. That way, your function can be called with mutable and read-only arrays alike. In addition, TypeScript will help you prevent accidental mutation of those parameters within the function.
If you want to experiment with read-only array types and play around with the above type annotations, I’ve prepared this TypeScript playground for you.
Read-Only Tuple Types in TypeScript
Similar to read-only array types, TypeScript lets us create read-only tuple types using the readonly
modifier:
|
|
Any attempt to mutate a value of a read-only tuple type will result in a type error:
|
|
For tuple types, there’s no equivalent of the ReadonlyArray
type. You’ll have to rely on the readonly
modifier to make a tuple type read-only.
Again, if you want to play around with tuple types and the readonly
modifier, feel free to use this TypeScript playground.