const
- 当用const定义原始数据类型时,修改变量会产生报错
- 当const定义对象类型时,const只是定义该对象指向的引用地址不可变,但是对于对象属性的修改,并没有限制。
In JavaScript, mutability is the default, although it allows variable declarations with
constto declare that the reference is immutable. The referent is still mutable: (在js里,可变是默认的,const只是声明引用是不可变,但是被引用对象是可变的)
const msg = 'hello'
const man = {
age: 2
}
// 报错:Cannot assign to 'msg' because it is a constant.
msg = 'world'
// 这里没有报错
man.age = 1
// 报错:Cannot assign to 'man' because it is a constant.
man = {}
readonly 修饰符
- readonly可以用来修饰类或者interface的属性,描述该属性是不可变的
class Cat {
readonly name: string
readonly address: {
code: string
}
}
interface Dog {
readonly name: string
readonly address: {
code: string
}
}
const dog1: Dog = {
name: 'd1',
address: {
code: '1'
}
}
// 这里没有报错
dog1.address.code = '2'
// 报错:Cannot assign to 'name' because it is a read-only property.
dog1.name = 'd2'
Readonly 工具类型
Readonly是个范型工具类型,用来描述浅层属性的不可变。 使一个本来默认可变的类型变为浅层不可变
/**
* Make all properties in T readonly
*/
type Readonly<T> = {
readonly [P in keyof T]: T[P];
};
interface Dog {
name: string
address: {
code: string
}
}
const dog1: Readonly<Dog> = {
name: 'd1',
address: {
code: '1'
}
}
// 这里依然不会报错
dog1.address.code = '2'
// 报错: Cannot assign to 'name' because it is a read-only property.
dog1.name = 'd2'
字面量常量断言
在typescript 3.4 中引入了常量断言, 常量断言会使对象深度不可变。常量断言的适用范围是字面量值
const dog1 = {
name: 'd1',
address: {
code: '1',
},
} as const
// Cannot assign to 'code' because it is a read-only property.
dog1.address.code = '2'
// Cannot assign to 'name' because it is a read-only property.
dog1.name = 'd2'
但是常量断言也有限制,就是使用了常量断言,就不能使用类型标注,否者常量断言不生效。
interface Dog {
name: string
address: {
code: string
}
}
// 这里同时使用了类型标注
const dog1: Dog = {
name: 'd1',
address: {
code: '1',
},
} as const
// 这里不会报错
dog1.address.code = '2'
// 这里不会报错
dog1.name = 'd2'
深层不可变
无论是const、readonly、还是Readonly都只能描述对象的浅层不可变。
那么有没有办法能够描述变量的深层不可变呢?
本身ts里是没有深层不可变这个范型的,但是我们可以参考Readonly范型,实现一个Immutable类型。
type Immutable<T> = {
readonly [K in keyof T]: Immutable<T[K]>;
};
interface Dog {
name: string
address: {
code: string
}
}
const dog1: Immutable<Dog> = {
name: 'd1',
address: {
code: '1',
},
}
// Cannot assign to 'code' because it is a read-only property.
dog1.address.code = '2'
// Cannot assign to 'name' because it is a read-only property.
dog1.name = 'd2'
也可以使用NPM上的ts-essentials包来实现