2024-05-06 20:40:05 +00:00
|
|
|
|
---
|
2024-10-30 17:34:11 +00:00
|
|
|
|
date: 2020-10-05
|
2024-05-06 20:40:05 +00:00
|
|
|
|
id: c0bc64a7-f2dc-4e2e-afb9-5dbc63eb8287
|
|
|
|
|
title: Readonly
|
|
|
|
|
---
|
|
|
|
|
|
|
|
|
|
# Introduction
|
|
|
|
|
|
|
|
|
|
[TypeScript's](20200929161126-typescript) type system allows you to mark
|
|
|
|
|
individual properties on [interfaces](20200929162220-interfaces),
|
|
|
|
|
[types](20200929163825-typescript_type_alias) and
|
|
|
|
|
[class](20201009104411-typescript_classes) properties as `readonly`.
|
|
|
|
|
|
|
|
|
|
# Examples
|
|
|
|
|
|
|
|
|
|
## interface
|
|
|
|
|
|
|
|
|
|
``` typescript
|
|
|
|
|
function foo(config: {
|
|
|
|
|
readonly bar: number,
|
|
|
|
|
readonly bas: number}) {// ..
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
let config = { bar: 123, bas: 123 };
|
|
|
|
|
foo(config);
|
|
|
|
|
// You can be sure that `config` isn't changed 🌹
|
|
|
|
|
```
|
|
|
|
|
|
|
|
|
|
## type
|
|
|
|
|
|
|
|
|
|
``` typescript
|
|
|
|
|
type Foo = {
|
|
|
|
|
readonly bar: number;
|
|
|
|
|
readonly bas: number;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
// Initialization is okay
|
|
|
|
|
let foo: Foo = { bar: 123, bas: 456 };
|
|
|
|
|
|
|
|
|
|
// Mutation is not
|
|
|
|
|
foo.bar = 456; // Error: Left-hand side of assignment expression cannot be a constant or a read-only property
|
|
|
|
|
```
|
|
|
|
|
|
|
|
|
|
## class property
|
|
|
|
|
|
|
|
|
|
``` typescript
|
|
|
|
|
class Foo {
|
|
|
|
|
readonly bar = 1; // OK
|
|
|
|
|
readonly baz: string;
|
|
|
|
|
constructor() {
|
|
|
|
|
this.baz = "hello"; // OK
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
```
|
|
|
|
|
|
|
|
|
|
``` typescript
|
|
|
|
|
type Foo = {
|
|
|
|
|
bar: number;
|
|
|
|
|
bas: number;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
type FooReadonly = Readonly<Foo>;
|
|
|
|
|
|
|
|
|
|
let foo: Foo = {bar: 123, bas: 456};
|
|
|
|
|
let fooReadonly: FooReadonly = {bar: 123, bas: 456};
|
|
|
|
|
|
|
|
|
|
foo.bar = 456; // Okay
|
|
|
|
|
fooReadonly.bar = 456; // ERROR: bar is readonly
|
|
|
|
|
```
|