TypeScript 如何做可变参数类型
你有没有过写JavaScript时,想写一个能接收任意数量参数的函数,却又想给这些参数定个规矩?比如写一个计算多个商品总价的函数,要求每个参数都得是数字,但又不想硬塞一堆参数进去,这时候就需要TypeScript的可变参数类型帮忙啦。
先搞懂:什么是“可变参数类型”?
简单说,就是允许函数接收任意数量的同类型或符合特定规则的参数,同时还能给这些参数加上类型限制,不会像JavaScript那样传错类型也不报错。比如你要写一个算总成绩的函数,想让它能接收2科、5科甚至100科的分数,还得保证每个分数都是数字,这就用到了TypeScript的可变参数类型。

用最常见的例子:算多笔消费的总金额
假设你开了个小水果店,想写个函数算顾客买几样东西的总钱数,要求每样都是数字,不能传字符串(比如把“10”当数字传),也不能传对象这种杂七杂八的类型。
如果用普通的JavaScript,你写的函数是这样的:
`javascript
function calculateTotal(...prices) {
return prices.reduce((sum, price) => sum + price, 0);
}
`
但这个函数有问题:你可以传calculateTotal(10, "20"),最后会返回"01020"(字符串拼接),完全不符合预期,而且TypeScript也没法提前拦住这种错误。
这时候TypeScript的可变参数类型就能搞定,只要给...prices加个类型就行:
`typescript
function calculateTotal(...prices: number[]) {
return prices.reduce((sum, price) => sum + price, 0);
}
`
现在再试calculateTotal(10, "20"),TypeScript会立刻报错,告诉你“第2个参数不能是字符串,得是数字”,是不是很实用?
进阶一点:参数不是完全同类型怎么办?
刚才的例子是所有参数都同类型,但有时候你想让参数符合特定的规则,比如要求第一个参数是商品名(字符串),后面任意数量是价格(数字),这时候就可以用元组类型的剩余元素,这是TypeScript里更灵活的可变参数类型用法。
比如你要写一个记录订单的函数,需要先传订单号(数字),然后传任意数量的商品价格,写法是这样的:
`typescript
function recordOrder(orderId: number, ...prices: number[]) {
const total = prices.reduce((sum, p) => sum + p, 0);
console.log(订单${orderId}总金额:${total}元);
}
`
现在调用recordOrder(123, 15, 22, 8)没问题,调用recordOrder(123, "22")会直接报错,因为剩余的prices要求都是数字,完美。
注意别踩这个小坑
有个新手容易错的地方:不要把普通变量和可变参数搞混。比如有人会写const nums = [1,2,3]; calculateTotal(nums),这时候TypeScript会报错,因为nums是数组类型,不是“零散的参数”,如果想传数组,要么直接把参数拆成零散的calculateTotal(...nums),要么直接给参数定义成number[],根据你的需求选就行。
其实TypeScript的可变参数类型,本质就是给JavaScript的扩展运算符...加上了类型校验,既保留了灵活传参的方便,又避免了JS那种“类型乱飘”的问题,日常写工具函数、处理批量数据的时候特别好用,不用再纠结参数传多传少、类型对不对啦。