Readonly 数组与不可变数据
使用 ReadonlyArray 防止意外修改。
Readonly 数组与不可变数据 是 CoddyKit 上的免费 TypeScript Academy 课时。 这是第 2 节课,共 4 节。 你可以在下方免费阅读本课时的完整内容 — 然后在浏览器中使用内置代码编辑器和全天候 AI 导师进行实践。 这是 TypeScript Academy 学习路径的一部分,你的进度在网页和 CoddyKit 应用中同步。 TypeScript Academy 课程共包含 4 节课。
欢迎
可变数组可能在代码的任何位置被意外修改。TypeScript 的 ReadonlyArray 和 readonly 修饰符可以帮助您强制执行不可变性。
数组上的 readonly 修饰符
在数组类型前添加 `readonly` 修饰符,可以防止修改数组。数组仍然可以读取,但不能更改。
const ids: readonly number[] = [1, 2, 3];
// ids.push(4); // Error
// ids[0] = 99; // Error
console.log(ids[0]); // OK — reading is fineReadonlyArray<T> 泛型形式
`ReadonlyArray` 是 `readonly T[]` 的泛型等价形式。两者都禁止使用 push、pop、splice 和索引赋值。
const names: ReadonlyArray<string> = ['Alice', 'Bob'];
// names.push('Charlie'); // Error从函数返回只读数组
让函数返回只读数组,可以向调用方表明不应修改该结果。
function getConfig(): readonly string[] {
return ['host', 'port', 'db'];
}不可变的函数参数
将数组参数标记为 readonly,可以防止函数修改调用方的数组。
function sum(nums: readonly number[]): number {
return nums.reduce((a, b) => a + b, 0);
// nums.push(99); // Error inside function
}使用 as const 创建字面量数组
`as const` 断言会使数组变为只读,并推断出元组类型,同时保留字面量元素类型,而不是将其扩宽。
const colors = ['red', 'green', 'blue'] as const;
// type: readonly ['red', 'green', 'blue']
// colors.push('yellow'); // ErrorReadonly 不会深度冻结
readonly 只能防止修改数组引用。如果元素是对象,它们的属性仍然可以更改。
const users: readonly { name: string }[] = [{ name: 'Alice' }];
// users.push({}); // Error
users[0].name = 'Bob'; // Allowed — object itself is mutable使用 Readonly<T> 实现深度不可变
若要让对象实现深度不可变,请将 ReadonlyArray 与元素上的 Readonly 结合使用。也可以使用 immer 等库。
type ImmutableUser = Readonly<{ name: string; scores: readonly number[] }>;
const u: ImmutableUser = { name: 'Alice', scores: [90, 85] };
// u.name = 'Bob'; // Error
// u.scores.push(100); // Error可变数组与只读数组的赋值
只读数组不能赋值给可变数组类型。这可以防止在需要修改数组的地方意外传入不可变数组。
const ro: readonly number[] = [1, 2];
const mutable: number[] = ro; // Error!何时使用只读数组
对于配置对象、常量、承诺不会修改的函数参数,以及纯函数的返回值,请使用只读数组。
展开会创建新的可变数组
将只读数组展开到新的数组字面量中,会创建一个可变副本。当您需要进行修改而不想直接改变原数组时,这是一个简洁的模式。
const base: readonly number[] = [1, 2, 3];
const extended: number[] = [...base, 4]; // new mutable array快速检查
在 TypeScript 中,对 `readonly number[]` 不允许执行哪种操作?
回顾
使用 `readonly T[]` 或 `ReadonlyArray` 防止修改数组。对字面量常量数组使用 `as const`。当需要扩展只读数组时,展开操作会创建一个可变副本。
常见问题解答
「Readonly 数组与不可变数据」课时是免费的吗?
是的 — 「Readonly 数组与不可变数据」的完整文本可在网页上免费阅读。要进行交互式练习(内置代码编辑器和全天候 AI 导师)并解锁 TypeScript Academy 课程的其余内容,请升级到 CoddyKit PRO。 TypeScript Academy 课程共包含 4 节课。
「Readonly 数组与不可变数据」这节课中我会学到什么?
使用 ReadonlyArray 防止意外修改。 你通过在浏览器中直接运行的动手代码来练习 TypeScript Academy,全天候 AI 导师会在你学习这节课的过程中回答你的问题。
学习 TypeScript Academy 需要有经验吗?
无需任何先前经验。CoddyKit 上的 TypeScript Academy 课程适合初学者到高级学习者,你可以从这里开始或从头开始,按照自己的节奏学习。 这是第 2 节课,共 4 节。
「Readonly 数组与不可变数据」课时需要多长时间?
大多数 CoddyKit 课程大约需要 5–10 分钟。每节课都很精短且互动,所以你能稳步进步,并在网页和应用中从离开的地方继续。
我能在这节 TypeScript Academy 课中编写并运行代码吗?
能。每节 TypeScript Academy 课都包含内置代码编辑器,你可以在浏览器中直接编写并运行真实代码,并获得即时 AI 反馈 — 无需本地设置。
此课程中的所有课时
- 类型化数组:T[] 与 Array
- Readonly 数组与不可变数据
- 元组:固定长度的类型化数组
- 枚举:数值常量与字符串常量