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

如何在TypeScript中按对象键调用不同参数的函数并规避类型错误?

问题分析与解决方案

原代码的核心问题在于:你用Record<string, (arg: base | base2) => string>强制统一了所有格式化函数的参数类型,但func1仅接受base类型、func2仅接受base2类型,二者并不兼容base | base2的联合类型(比如func1无法处理base2类型的参数),因此会触发类型错误。

下面提供两种优雅的解决方案,既保留抽象调用的能力,又保证类型安全:


方案1:明确绑定键与函数类型

直接定义一个精准的Formatter类型,让每个键对应正确的函数签名:

interface base {
    name: string;
}
interface base2 {
    title: string;
}

const func1 = (arg: base) => {
    return arg.name;
}

const func2 = (arg: base2) => {
    return arg.title;
}

// 明确每个键对应的函数类型
type Formatter = {
    format: typeof func1;
    format2: typeof func2;
};

const formatter: Formatter = {
    format: func1,
    format2: func2
}

// 类型安全的调用,无错误
formatter["format"]({ name: "test" });
formatter["format2"]({ title: "demo" });

方案2:映射类型实现可扩展的抽象

如果需要后续扩展更多格式化函数,可以用映射类型将键与参数类型绑定,实现更灵活的抽象:

interface base {
    name: string;
}
interface base2 {
    title: string;
}

// 定义键到参数类型的映射关系
type FormatterParamMap = {
    format: base;
    format2: base2;
    // 后续新增格式化规则时,直接在这里添加键和对应的参数类型即可
};

// 根据映射关系自动生成Formatter类型
type Formatter = {
    [Key in keyof FormatterParamMap]: (arg: FormatterParamMap[Key]) => string;
};

// 实现格式化函数
const func1 = (arg: base) => arg.name;
const func2 = (arg: base2) => arg.title;

const formatter: Formatter = {
    format: func1,
    format2: func2
};

// 类型安全的调用
formatter.format({ name: "test" });
formatter.format2({ title: "demo" });

// 动态调用时也能保证类型安全
function callFormatter<Key extends keyof Formatter>(key: Key, arg: FormatterParamMap[Key]) {
    return formatter[key](arg);
}

callFormatter("format", { name: "dynamic test" });

这两种方案都能让TypeScript准确推断每个函数的参数类型,避免类型错误的同时,保留了通过键名调用函数的抽象能力。

内容的提问来源于stack exchange,提问作者Ali Osman

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.08.04 06:35:15