ts中 readonly 的使用

1.2k words

使用 readonly 所装饰的数据, 无论为[变量|常量|属性] 均无法修改, 只能读取。

1
2
3
const nums = [1, 2, 3] // 此时类型为  nums: number[]

nums[0] = 123 // 可修改

类型可修改

使用 as const 添加 readonly 特性

1
2
3
const nums = [1, 2, 3] as const // 此时类型为  nums: [1, 2, 3]

nums[0] = 123 // 无法修改,且抛出异常

 `readonly` 特性

readonly 可以推导到具体的值, 例如

类型推导

1
2
3
4
5
// 这里只能告诉你 name为 `string`, age为`number`
const aBoy = {
name: '小明',
age: 18,
}

前者可以单独为某一个属性添加, 后者为所有的属性添加

1
2
3
4
5
6
7
8
9
const aBoy = {
name: '小明' as const,
age: 18 as const,
}

const aBoy2 = {
name: '小明',
age: 18,
} as const

redaonly设置

🌰 举个例子

包括但不限于 hiddens 过滤, 配合 readonly 还能实现更高级 获取器 getter 设置器 setter 操作并返回最终类型

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
/** 基础模型类 */
abstract class BaseModel<D extends Record<string, unknown>> {
abstract readonly hiddens: Array<keyof D>
constructor(private data: D) {}

toJSON() {
const { hiddens, data } = this
// 过滤 hiddens 存在的字段
const keys = Object.keys(data).filter((key) => !hiddens.includes(key))
const entries = keys.map((key) => [key, data[key]])

// 产生一个新的对象
const newData = Object.fromEntries(entries)

// 此时 newData 的类型为 `D` 并且排除 `this['hiddens']`
return newData as Omit<D, this['hiddens'][number]>
}
}

/** 基础并实现 */
class BoyModel extends BaseModel<{
name: string
age: number
xx: string // 用于排除
}> {
hiddens = ['xx' as const]
}

实例化模型后可得
Alt text