TypeScript中test[]与[test]两种方括号类型写法是否存在差异?
关于TypeScript中
test[]与[test]的类型差异辨析 你观察到二者在示例场景下表现等效,本质是测试用例刚好落在了两个类型的合法取值交集范围内,两种记号的底层类型定义、约束规则存在本质区别,具体差异如下:
两种记号的本质定义
test[]是动态长度数组类型,表示所有元素都为test结构的可变长度数组:长度没有固定约束,可以是0、1、任意正整数,元素顺序也没有严格的位置绑定。[test]是固定长度元组类型,表示长度被严格锁定为1的结构化数组:仅允许数组下标0的位置存在test类型的值,不允许出现第2个元素,也不允许空数组。
能明确暴露差异的测试场景
你之前的示例中,两个变量被赋值的都是长度恰好为1、元素符合test结构的数组,这类值同时满足两个类型的校验规则,所以看起来没有区别。只要跳出这个交集范围,差异就会完全显现:
1. 长度校验规则差异
interface test { a: string; b: string; } // 对动态数组类型来说,任意合法元素数量都是允许的 const x0: test[] = [] // 编译通过:空数组合法 const x1: test[] = [{a: "aaaa", b: "bbbb"}] // 编译通过:长度为1合法 const x2: test[] = [{a: "a1", b: "b1"}, {a: "a2", b: "b2"}] // 编译通过:长度为2合法 // 对定长元组类型来说,长度必须严格等于1 const y0: [test] = [] // 编译报错:元组要求长度为1,当前值长度为0 const y1: [test] = [{a: "aaaa", b: "bbbb"}] // 编译通过:刚好符合长度要求 const y2: [test] = [{a: "a1", b: "b1"}, {a: "a2", b: "b2"}] // 编译报错:元组长度固定为1,当前值长度为2
2. 内置属性的类型推断差异
动态数组和定长元组的内置属性存在明确的类型边界:
// 动态数组的length是通用number类型,匹配可变长度的特性 x1.length // 推断结果为number // 定长元组的length是固定字面量类型,匹配定长特性 y1.length // 推断结果为字面量类型1,而非通用number
3. 解构取值的类型精度差异
因为定长元组明确知道每个下标位置必然存在值,解构时拿到的值类型会比动态数组更精确:
// 动态数组解构:编译器无法保证下标0一定有值(数组可能为空),开启严格索引检查后,推断得到的类型是 test | undefined const [elementFromX] = x1 // 定长元组解构:编译器明确知道下标0位置必然存在test类型的值,推断得到的类型是纯test,不存在undefined的可能 const [elementFromY] = y1
内容的提问来源于stack exchange,提问作者oliveCshws
相关产品推荐
相关产品推荐

