TypeScript 如何定义元组类型
在写代码的时候,你肯定见过这种场景:想存一组数据,一个是“苹果”,一个是5块钱,一个是“山东产”——三种类型完全不一样,普通数组却只能存同类型数据,比如把字符串和数字塞一起,编辑器还会飘红提醒。这时候TypeScript的元组,就是专门给这种“固定数量、每个位置类型都定死”的场景设计的。
什么是元组?用生活里的“固定套餐”举例子
你可以把元组理解成“打包好的固定规格包裹”:就像奶茶店的“中杯套餐”,必须是1杯奶茶+1份小料,少一样不行,多一样也不行,而且奶茶是液体(字符串)、小料是固体(比如珍珠,也用字符串),各自的类型不能乱换。

比如你要存一个“用户的基础信息”,得是“姓名(字符串)+年龄(数字)+是否会员(布尔值)”,三个数据,位置、类型全固定,用数组的话就会乱:数组会把所有数据当成同一种类型,你没法保证第三个位置一定是布尔值,而元组能把每个位置的要求卡死。
怎么定义元组?代码里的“规格说明”
在TypeScript里,定义元组的方式很简单,直接在数组类型里按顺序写每个位置的类型就行,用方括号包起来,像给数组加了“类型位置限制”。
举个最常用的小例子:
`typescript
// 定义一个元组,位置0是姓名(字符串),位置1是年龄(数字)
let userInfo: [string, number];
// 符合要求的赋值:位置0是字符串,位置1是数字,刚好两个,完美
userInfo = ["张三", 25];
// 错误示范1:位置1写成字符串,类型不匹配,编辑器直接报错
userInfo = ["张三", "25"];
// 错误示范2:只给一个值,少了一个,也报错
userInfo = ["张三"];
// 错误示范3:多给了一个值,三个位置,元组只允许两个,也报错
userInfo = ["张三", 25, "北京"];
`
是不是和生活里的“固定套餐”一模一样?多一样少一样、类型不对都不行。
元组的进阶用法:可选元素和剩余元素
有时候你的元组不用那么死,比如“用户信息”里的“籍贯”是可选的,没填的话也没事,这时候可以给最后一个位置加?,表示可选:
`typescript
// 最后一个位置是可选的字符串
let userWithAddress: [string, number, string?];
// 可以只传前两个
userWithAddress = ["李四", 30];
// 也可以加上第三个(籍贯)
userWithAddress = ["李四", 30, "上海"];
`
还有一种情况,你不确定最后要加多少个元素,比如“订单明细”,除了固定的“订单号(数字)+商品名(字符串)”,后面可以跟任意数量的价格,这时候用剩余元素语法...:
`typescript
// 第一个位置是订单号,第二个是商品名,后面跟任意数量的数字
let order: [number, string, ...number[]];
// 符合要求:后面跟两个价格(运费和手续费)
order = [1001, "笔记本", 19.9, 5];
// 也可以后面跟0个价格
order = [1002, "鼠标"];
`
为什么要用元组?比普通数组靠谱在哪?
很多人会问:“普通数组也能存不同类型的东西,为什么要用元组?”其实核心就是“安全”:比如你要写一个函数,返回“坐标(x, y)”,如果用数组number[],你拿到结果后,没法确定第一个元素是x还是y,甚至会不会是字符串;而用元组[number, number],你取的时候,TypeScript会知道第一个是x,第二个是y,编辑器不会让你随便拿错,也不会出现“不小心把年龄当成姓名”的低级错误。
简单说,元组就是给“有固定顺序、固定类型、固定数量”的数据加了一层“类型枷锁”,既能存不同类型的数据,又不会像普通数组那样乱套——就像你带外卖,装在固定规格的餐盒里,不会洒出来,也不会漏放东西。