TypeScript实现函数第二个参数支持剩余参数与对象参数
正确实现方案
要实现这种支持两种参数形式的函数,TypeScript里有两种可靠的方式,解决你之前遇到的参数隐式any问题:
方案一:使用函数重载签名(推荐)
这是TypeScript实现函数重载的标准方式,先定义不同调用场景的签名,再写统一实现:
type ConfigT = { key1?: boolean; key2?: string; } // 定义两种重载签名,对应两种调用方式 function test(one: string, ...rest: Array<boolean | string>): void; function test(one: string, rest: ConfigT): void; // 实现签名,处理两种情况的逻辑 function test(one: string, ...restArgs: any[]) { console.log("ONE ", one); // 通过参数长度和类型判断区分场景 if (restArgs.length === 1 && typeof restArgs[0] === 'object' && restArgs[0] !== null) { const config = restArgs[0] as ConfigT; console.log("配置对象: ", config); } else { console.log("剩余参数数组: ", restArgs); } } // 调用示例 test("hello", true, "world"); // 匹配剩余参数重载 test("hi", { key1: false, key2: "test" }); // 匹配配置对象重载
方案二:显式指定参数类型并使用类型守卫
如果你坚持用联合类型定义函数,可以给参数显式指定类型,再通过类型守卫区分逻辑:
type ConfigT = { key1?: boolean; key2?: string; } type testFuncTRestArr = (one: string, ...rest: Array<boolean | string>) => void; type testFuncTRestObj = (one: string, rest: ConfigT) => void; const test: testFuncTRestArr | testFuncTRestObj = (one: string, ...rest: Array<boolean | string> | [ConfigT]) => { console.log("ONE ", one); if (rest.length === 1 && typeof rest[0] === 'object' && rest[0] !== null) { const config = rest[0] as ConfigT; console.log("配置对象: ", config); } else { console.log("剩余参数数组: ", rest); } }; // 调用示例 test("hello", true, "world"); test("hi", { key1: false, key2: "test" });
为什么之前的代码报错?
当你用函数类型联合定义变量时,TypeScript无法自动推断实现函数的参数类型(联合函数的参数是逆变的,会被收窄到any),所以必须显式指定参数类型,或者用重载签名来明确类型约束。
内容的提问来源于stack exchange,提问作者Aldhaneka
相关产品推荐
相关产品推荐

