typescript 中合法语法是 ...args: t[] 而非 t...args,rest 参数用 ... 将不定数量实参收集为数组,必须位于参数末尾、仅一个,支持类型约束与泛型推导,替代无类型的 arguments。

在 TypeScript 中,T...args 并不是合法语法。真正用于接收任意数量参数的是 rest 参数(Rest Parameters),写法是 ...args: T[] 或更常见的是 ...args: any[],配合类型约束使用。它的核心是用三个点 ... 把剩余参数收集为一个数组,而不是某种泛型写法 T...args。
什么是 rest 参数?
rest 参数允许函数接受不定数量的实参,并将它们自动组装成一个数组。它必须是函数参数列表中的最后一个参数,且只能有一个。
- 语法:用
...name: Type声明,比如...numbers: number[] - 作用:替代
arguments对象,更类型安全、更直观 - 限制:不能放在普通参数前面,也不能和多个 rest 参数共存
怎么正确声明 rest 参数的类型?
推荐显式标注类型,避免用 any。常见写法有:
-
...items: string[]—— 只接受字符串列表 -
...values: (string | number)[]—— 混合类型数组 -
...args: unknown[]—— 安全兜底,后续再做类型判断 - 结合泛型:
function sum<t extends number>(...nums: T[]): T</t>—— 限定传入值必须是 number 的子类型
实际例子:封装一个通用日志函数
比如想让 log 函数能打印任意内容,同时保留类型提示:
function log(...messages: unknown[]): void {
console.log('[LOG]', ...messages);
}
log('User logged in', 123, { id: 1 }); // ✅ 正常运行
log(); // ✅ 允许零个参数
如果希望更强的类型推导,可用泛型 + rest:
function tuple<t extends unknown>(...args: T): T {
return args;
}
const result = tuple('hello', 42, true); // 类型是 [string, number, boolean]
</t>
常见错误和注意事项
初学者容易踩的坑:
- 写成
args...: string[]或T...args—— 顺序和语法都不对,正确是...args: string[] - 把 rest 参数放在其他参数前面,如
function f(...args, flag: boolean)—— 编译报错 - 混用 rest 和
arguments—— 在 TypeScript 中应优先用 rest,arguments无类型信息 - 忘记 rest 参数本质是数组,直接当单个值用,比如
args.toUpperCase()—— 应该写args[0]?.toString().toUpperCase()
不复杂但容易忽略:rest 参数不是语法糖,它是 JavaScript 标准特性,TypeScript 在其基础上增加了类型检查能力。写对三点位置和类型标注,就能安全地处理“不确定几个参数”的场景。











