TypeScript 剩余参数与展开语法详解
剩余参数收集任意数量实参,展开语法把数组/对象铺开。TypeScript 让两者全程类型安全。本文讲解可变参数函数、数组对象展开与类型推导。
... 双向工作:函数签名中 ...args: number[] 收集剩余参数为数组(rest);调用处 fn(...arr) 把数组展开为实参(spread)。TypeScript 对两者做完整类型检查——可变参数函数因此类型安全。
可变参数问题
老式 JavaScript 用 arguments 对象处理不定参数——无类型、非真数组、箭头函数中不可用。剩余参数是现代化解法。
剩余参数
function sum(...numbers: number[]): number {
return numbers.reduce((a, b) => a + b, 0);
}
sum(1, 2, 3); // 6
sum(); // 0——numbers 是 [],不是 undefined
// 与普通参数组合(rest 必须最后)
function log(level: string, ...messages: string[]) {
messages.forEach(m => console.log(`[${level}] ${m}`));
}
规则:rest 参数必须是最后一个参数,类型标注为数组。
数组展开
const arr = [1, 2, 3] as const;
Math.max(...arr); // 展开为三个实参
// 数组合并与拷贝
const merged = [...a, ...b];
const copy = [...original]; // 浅拷贝
对象展开与组合
const defaults = { theme: 'light', pageSize: 20 };
const config = { ...defaults, pageSize: 50 }; // 后者覆盖前者
// 解构 + rest 收集剩余属性
const { password, ...safeUser } = user; // 剔除敏感字段的经典模式
覆盖顺序:后面的属性覆盖前面的——默认配置在前、用户配置在后是标准模式。
TypeScript 的类型安全加成
- rest 参数的类型数组被精确检查:
sum('1', 2)编译报错; - 对象展开的类型被正确推导:交叉属性类型自动合并;
- 元组 rest(
...[string, number])支持精确参数序列——高阶函数的类型化基础。
常见问题(FAQ)
Q:rest 参数和普通数组参数怎么选?
调用方是"逐个传值"的场景用 rest(sum(1,2,3) 比 sum([1,2,3]) 自然);数据本来就是数组的用数组参数。API 的人体工学直觉是标准。
Q:展开大数组有坑吗?
有——fn(...hugeArray) 会撑爆参数数量上限(栈溢出)。大数组场景改用数组参数传递。
Q:对象展开是深拷贝吗?
浅拷贝——嵌套对象仍是引用。深拷贝用 structuredClone()(Node 17+)。
参考文档
本文依据公开文档整理,示例需按项目依赖版本验证;不将文档中的性能描述视为本项目实测结果。