TypeScript 中 Array 与 Tuple 在 length 属性上的类型差异

在 TypeScript 中,数组(Array)和 元组(Tuple) 是处理集合数据的两种常见方式。它们在类型系统中的表现各有特点,尤其是在处理 length 这一属性时。本文将介绍数组与元组在 length 属性上的类型差异。

Array 类型的 length

在 TypeScript 中,数组类型通常被视为元素类型的集合,而其长度则是灵活可变的。例如,当我们定义了一个字符串数组类型 string[],TypeScript 会将该类型的 length 属性视为 number 类型。这是因为所有数组实例在 JavaScript 中都有一个 length 属性,表示数组中元素的数量。

typescript 复制代码
type ArrayType = string[]; // 定义一个数组类型
// 在类型系统中,数组类型的 length 属性为 number 类型
type ArrayLength = ArrayType['length']; // 类型是 number

然而,TypeScript 并不关心数组的具体长度,因为数组可以动态增长或缩短。因此,无论数组实际包含多少元素,其 length 属性的类型始终是 number,这反映了数组在运行时的动态性。

Tuple 类型的长度

与数组不同,Tuple 类型是具有固定长度和已知元素类型的数组。在 TypeScript 中,Tuple 的长度是其类型签名的一部分,这意味着 length 属性具有精确的类型表示。

以一个包含字符串和数字的 Tuple 类型 [string, number] 为例,其 length 属性的类型将是一个具体的数字字面量,准确地反映了 Tuple 中元素的数量。

typescript 复制代码
type TupleType = [string, number]; // 定义一个 Tuple 类型
// Tuple 类型的 length 属性是一个具体的数字字面量类型
type TupleLength = TupleType['length']; // 类型是 2,因为 Tuple 有两个元素

这种精确的长度类型为 TypeScript 提供了额外的类型安全性,因为它确保了 Tuple 的长度在编译时是固定的,这与数组类型提供的灵活性形成鲜明对比。

判断类型是否为 Tuple

TS 类型体操项目 type-challenges 中有道题是 IsTuple,判断类型 T 是否为 Tuple 类型,下面是一些测试用例。

typescript 复制代码
type case1 = IsTuple<[number]>; // true
type case2 = IsTuple<readonly [number]>; // true
type case3 = IsTuple<number[]>; // false

一般涉及到 Tuple, 我们自然会想到判断类型的 length 属性,我最初写的代码如下:

typescript 复制代码
type IsTuple<T> = T extends readonly any[]
  ? T['length'] extends number
    ? true
    : false
  : false;

但是只能满足 case1 和 case2,而 case3 我们期望是 false,上面的写法也会为 true。

这时候就需要用到本篇文章讲的知识点来排除 T 为数组的情况了,我们反过来使用 number extends T['length'] 来判断,如果满足条件,说明 T['length'] 类型为 number,那么 T 为数组,返回 false。

typescript 复制代码
type IsTuple<T> = T extends readonly any[]
  ? number extends T['length']
    ? false
    : true
  : false;

总结

TypeScript 的 Array 类型和 Tuple 类型在处理 length 属性时展现了不同的类型特性:

  • 数组类型的 length 属性为 number,反映了数组在运行时可以动态变化的特性。
  • Tuple 类型的 length 属性是一个具体的数字字面量,确保了 Tuple 的长度在编译时是固定且类型安全的。

这种差异体现了 TypeScript 类型系统的深度和灵活性,允许开发者在不同的场景下选择最合适的类型来表达数据结构。通过对这些细微差别的理解,我们可以更加精确地控制类型,从而编写出更可靠、更易于维护的代码。

相关推荐
武清伯MVP12 小时前
阮一峰《TypeScript 教程》学习笔记——基本用法
笔记·学习·typescript
ttod_qzstudio2 天前
解决 Vue 3 + TypeScript 中 v-for 循环类型推断问题
前端·vue.js·typescript
今天头发还在吗2 天前
【React】动态SVG连接线实现:图片与按钮的可视化映射
前端·javascript·react.js·typescript·前端框架
冷冷的菜哥2 天前
react多文件分片上传——支持拖拽与进度展示
前端·react.js·typescript·多文件上传·分片上传
Kisang.2 天前
【HarmonyOS】窗口管理实战指南
前端·华为·typescript·harmonyos·鸿蒙
Dajiaonew3 天前
Vue3 + TypeScript 一篇文章 后端变全栈
前端·javascript·typescript
敲敲敲敲暴你脑袋3 天前
用3Dmol.js展示3D分子结构
typescript·webgl·数据可视化
还是大剑师兰特3 天前
TypeScript 面试题及详细答案 100题 (11-20)-- 基础类型与类型操作
typescript·大剑师·typescript教程·typescript面试题
用户47949283569153 天前
TypeScript 和 JavaScript 的 'use strict' 有啥不同
前端·javascript·typescript
用户47949283569154 天前
还不知道'use strict'的作用?这篇文章给你讲清楚
前端·javascript·typescript