本文首发于我的个人Blog阿西BUG,欢迎大家批评指正
readonly 属性修饰符
readonly 是一个属性(property) 修饰符,顾名思义,在 TypeScript 中它可以把一个属性变成只读的。我们可以在 class/interface/type 定义中使用它,也可以用来定义一个函数的参数。既然是只读的意味着一旦定义了就不能再修改,所以这些属性必须在声明的时候或者在类中对它进行初始化。
TypeScript 类型系统允许你在一个 function 里使用 readonly 来标记参数属性。它能让你以一种更安全的方式工作(不可预期的改变通常会带来很糟糕的后果)。
1
2
3
4
5
6
7
8 function foo(config: { readonly bar: number, readonly bas: number }) {
// ..
}
const config = { bar: 123, bas: 123 };
foo(config);
// 现在你能够确保 'config' 不能够被改变了
当然,你也可以在 interface 和 type 里使用 readonly:1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18// type
type Foo = {
readonly bar: number;
readonly bas: number;
};
// 初始化
const foo: Foo = { bar: 123, bas: 456 };
// 不能被改变
foo.bar = 456; // Error: foo.bar 为仅读属性
// interface
interface Foo {
readonly [x: number]: number;
}
// 使用
const foo: Foo = { 0: 123, 2: 345 };
console.log(foo[0]); // ok(读取)
foo[0] = 456; // Error: 属性只读
你也能指定一个类的属性为只读,然后在声明时或者构造函数中初始化它们,如下所示:1
2
3
4
5
6
7class Foo {
readonly bar = 1; // OK
readonly baz: string;
constructor() {
this.baz = 'hello'; // OK
}
}
Readonly 映射类型
对于每个属性都要写一个 readonly 的做法实在是不够优雅。作为一个推崇 Less is more (lan duo) 的人,能够少写一点就尽量少写。有没有一种方法可以一键给所有属性添加 readonly 定义呢?有的,官方标准库 lib.es5.d.ts 提供了一个方法 Readonly
把对象上所有属性变为只读。
1 | type Foo = { |
NOTE: 需要注意的是,Readonly1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21interface foo {
readonly bar: string;
readonly baz: {
hoo: number;
}
}
const fuu: foo = {
bar: 'bar',
baz: {
hoo: 1
}
}
fuu.baz = { hoo: 2 } // ❌
fuu.baz.hoo = 3; // ✅
// 要在嵌套里面再使用 Readonly<T>
interface foo {
readonly bar: string;
readonly baz: Readonly<{
hoo: number;
}>
}
与 const 区别
const
:
- 用于变量;
- 变量不能重新赋值给其他任何事物
readonly
:
- 用于属性
- 用于别名,可以修改属性
eg:1
2
3
4const foo = 123; // 变量
let bar: {
readonly bar: number; // 属性
};