Array<Type> vs Type[] 在 TypeScript 中:你必须赢得的语法之战
\n\n如果你曾经写过 TypeScript,你一定见过两种声明数字数组的方式:
\n\nconst numbers1: number[] = [1, 2, 3];\nconst numbers2: Array<number> = [1, 2, 3];\n\n两种方式都有效。两种都能编译。两种都是合法的 TypeScript。那么为什么围绕它们会有这么多争论?为什么这个问题在 Stack Overflow 上获得了数千次浏览?最重要的是——如何避免那些会毁掉你项目的陷阱?
\n\n让我们一劳永逸地搞清楚。没有枯燥的理论。只有实战中真正有用的内容。
\n\n快速入门:它们是什么
\n\nType[] 语法(数组字面量语法)
\n\n这是在 TypeScript 中声明数组最常见的方式。它源自 JavaScript,看起来非常自然:
\n\nlet fruits: string[] = ['apple', 'banana', 'cherry'];\nlet matrix: number[][] = [[1, 2], [3, 4]]; // 数组的数组\n\n简洁、可读、直观。对于 90% 的情况来说,这已经足够了。
\n\nArray<Type> 语法(泛型语法)
\n\n这是使用内置接口 Array<T> 的泛型形式:
let fruits: Array<string> = ['apple', 'banana', 'cherry'];\nlet matrix: Array<Array<number>> = [[1, 2], [3, 4]];\n\n看起来更“学术”,但在复杂场景下提供了更大的灵活性。
\n\n即使是经验丰富的开发人员也会犯的 5 大错误
\n\n错误 #1:盲目信任 IDE 的自动补全
\n\n你的 IDE 可能会提示这两种方式。但这并不意味着它们在任何地方都可以互换。来看一个 联合类型 的例子:
\n\n// 这样可以\ntype Status = 'active' | 'inactive';\nconst statuses1: Status[] = ['active', 'inactive'];\n\n// 但这样会报语法错误!\n// const statuses2: Array<'active' | 'inactive'> = ['active', 'inactive']; \n// ❌ 错误:应为 ';'\n\n// 使用泛型的正确方式:\nconst statuses3: Array<Status> = ['active', 'inactive'];\n\n结论: 在 Array<> 内部不能直接使用复杂的联合类型。请先将它们提取为单独的类型。
错误 #2:混淆 readonly 数组
\n\n当需要使数组不可变时,两种语法的表现不同:
\n\n// ✅ 使用 Type[] 正确\nconst readonlyFruits: readonly string[] = ['apple', 'banana'];\n// readonlyFruits.push('orange'); // ❌ 错误:只读\n\n// ❌ 这样不行:\n// const wrong: readonly Array<string> = ['apple']; \n// 错误:'readonly' 修饰符只能出现在数组类型上\n\n// ✅ 使用 Array<> 的正确方式——使用 ReadonlyArray:\nconst correct: ReadonlyArray<string> = ['apple', 'banana'];\n\n结论: 对于 readonly 数组,使用 readonly Type[] 或 ReadonlyArray<Type>。不能将 readonly 与 Array<> 混用。
错误 #3:多层数组的问题
\n\n当数组包含其他数组时,Array<> 语法会变得冗长:
// 可读且清晰\nconst grid1: number[][] = [[1, 2], [3, 4]];\n\n// 已经较难阅读\nconst grid2: Array<Array<number>> = [[1, 2], [3, 4]];\n\n// 如果是三层呢?噩梦:\nconst cube: Array<Array<Array<number>>> = [[[1]]]; // 🤯\n\n// 使用 Type[] 更简单:\nconst cube2: number[][][] = [[[1]]];\n\n结论: 对于嵌套层级超过 2 的数组,使用 Type[][]。你的同事会感谢你的。
错误 #4:忽略使用上下文
\n\n在某些框架(Angular、React)和库中,有特定的风格约定。违反约定可能会引起混淆:
\n\n// Angular 经常