You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

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

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.07.17 18:57:26