TypeScript Academy · 课时

readonly 数组与元组

防止数组和元组调用会改变其内容的方法。

第 2 / 4 课13 个步骤

readonly 数组与元组 是 CoddyKit 上的免费 TypeScript Academy 课时。 这是第 2 节课,共 4 节。 你可以在下方免费阅读本课时的完整内容 — 然后在浏览器中使用内置代码编辑器和全天候 AI 导师进行实践。 这是 TypeScript Academy 学习路径的一部分,你的进度在网页和 CoddyKit 应用中同步。 TypeScript Academy 课程共包含 4 节课。

只读数组

只读数组可以读取,但不能修改。您可以将其写作 readonly number[],或等价地写作 ReadonlyArray<number>。元素类型保持不变,只有修改操作会被阻止。

const nums: readonly number[] = [1, 2, 3];
console.log(nums[0], nums.length);
// nums[0] = 9; // Error: index signature is readonly

ReadonlyArray 类型

ReadonlyArray<T> 是泛型形式,其含义与 readonly T[] 完全相同。请选择可读性更好的写法;两者可以互换。

const names: ReadonlyArray<string> = ['Ada', 'Sam'];
console.log(names.join(', '));

没有修改方法

只读数组会完全省略会修改数据的方法。push、pop、splice、sort 和 reverse 都不可用——这种类型实际上根本没有这些方法。

const items: readonly string[] = ['a', 'b'];
// items.push('c'); // Error: push does not exist
// items.splice(0, 1); // Error
console.log(items.length);

不修改数据的方法仍可用

那些返回新值而不是修改原数据的方法仍然可用,例如 map、filter、concat 和 slice。它们会生成新数组,不会改变原数组。

const nums: readonly number[] = [1, 2, 3];
const doubled = nums.map((n) => n * 2);
console.log(doubled); // new array, nums unchanged

将只读数组用作参数

在函数中接受 readonly T[],表示您不会修改调用方的数组。它既能说明意图,也能让编译器强制执行这一约定。

function sum(values: readonly number[]): number {
  return values.reduce((a, b) => a + b, 0);
}
console.log(sum([10, 20, 30]));

可变数组可赋给只读类型

普通的 number[] 可以赋给 readonly number[] 参数——您只是在承诺不会修改它。反过来则不允许。

function total(v: readonly number[]): number {
  return v.reduce((a, b) => a + b, 0);
}
const mutable: number[] = [1, 2, 3];
console.log(total(mutable)); // ok

只读元组

元组也可以是只读的:readonly [string, number]。元素类型和顺序都是固定的,单个位置也不能重新赋值。

const pair: readonly [string, number] = ['age', 30];
console.log(pair[0], pair[1]);
// pair[1] = 31; // Error: readonly tuple

只读元组禁止修改

与只读数组一样,只读元组会移除修改方法,并拒绝索引赋值。它们非常适合表示固定形状的记录,例如坐标对。

const point: readonly [number, number] = [3, 4];
// point.push(5); // Error
// point[0] = 0; // Error
console.log(point[0] + point[1]);

常量断言与只读类型的区别

有两种方式可以获得只读数组,它们之间存在细微差异。readonly number[] 注解会保留通用的元素类型。as const 更进一步:它会将数组转换为由字面量类型组成的只读元组。

const a: readonly number[] = [1, 2, 3]; // elements: number
const b = [1, 2, 3] as const;            // readonly [1, 2, 3]
console.log(a[0], b[0]);

如何选择

如果只需要不可变性而不需要限定具体的元素类型,请使用 readonly T[] 注解。如果还需要确切的字面量值,例如为了派生联合类型,请使用 as const。

const DAYS = ['Mon', 'Tue', 'Wed'] as const;
type Day = typeof DAYS[number]; // 'Mon' | 'Tue' | 'Wed'
const d: Day = 'Tue';
console.log(d);

共享数据的不可变性

只读数组和元组可以保护共享常量与配置列表,防止它们被意外修改,从而在编译时杜绝因意外修改导致的错误。

const ALLOWED_PORTS: readonly number[] = [80, 443, 8080];
function isAllowed(p: number): boolean {
  return ALLOWED_PORTS.includes(p);
}
console.log(isAllowed(443), isAllowed(22));

快速检查

检验您对只读数组和元组的理解。

回顾:只读数组和元组

您已了解到:

  • readonly T[] / ReadonlyArray<T> 会阻止修改,但允许读取和调用不修改数据的方法。
  • push/splice 等修改方法会从类型中移除。
  • 只读元组会固定长度和元素类型。
  • as const 更进一步,会生成由字面量类型组成的只读元组。

接下来学习只读集合类型。

const config: readonly string[] = ['a', 'b'];
const upper = config.map((s) => s.toUpperCase());
console.log(upper);
免费开始

用 AI 导师学习 TypeScript — 免费

在浏览器中编写并运行真实代码,获得全天候 AI 导师的即时帮助,并在网页或应用中继续学习。

课程
101
课程
352

常见问题解答

「readonly 数组与元组」课时是免费的吗?

是的 — 「readonly 数组与元组」的完整文本可在网页上免费阅读。要进行交互式练习(内置代码编辑器和全天候 AI 导师)并解锁 TypeScript Academy 课程的其余内容,请升级到 CoddyKit PRO。 TypeScript Academy 课程共包含 4 节课。

「readonly 数组与元组」这节课中我会学到什么?

防止数组和元组调用会改变其内容的方法。 你通过在浏览器中直接运行的动手代码来练习 TypeScript Academy,全天候 AI 导师会在你学习这节课的过程中回答你的问题。

学习 TypeScript Academy 需要有经验吗?

无需任何先前经验。CoddyKit 上的 TypeScript Academy 课程适合初学者到高级学习者,你可以从这里开始或从头开始,按照自己的节奏学习。 这是第 2 节课,共 4 节。

「readonly 数组与元组」课时需要多长时间?

大多数 CoddyKit 课程大约需要 5–10 分钟。每节课都很精短且互动,所以你能稳步进步,并在网页和应用中从离开的地方继续。

我能在这节 TypeScript Academy 课中编写并运行代码吗?

能。每节 TypeScript Academy 课都包含内置代码编辑器,你可以在浏览器中直接编写并运行真实代码,并获得即时 AI 反馈 — 无需本地设置。

此课程中的所有课时

  1. readonly 属性
  2. readonly 数组与元组
  3. ReadonlyArray 与 ReadonlyMap
  4. 深度不可变模式
← 返回 TypeScript Academy