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

TypeScript中如何基于数据类型实现动态函数调用?

TypeScript 类型安全的函数映射表实现

针对你遇到的联合类型分发时无法自动收窄类型的问题,可以通过类型映射+泛型约束的方式实现类型安全的函数映射表,彻底摆脱重复的switch逻辑,同时保证TypeScript的类型检查。

步骤1:定义DataType与数据类型的映射

首先创建一个类型,明确每个DataType对应的具体数据结构:

enum DataType {
    A = 'A',
    B = 'B',
}

interface DataA {
    id: number;
    type: DataType.A;
    fieldA: string;
}

interface DataB {
    id: number;
    type: DataType.B;
    fieldB: string;
}

// 定义DataType到对应数据类型的映射
type DataMap = {
    [DataType.A]: DataA;
    [DataType.B]: DataB;
};

步骤2:定义通用处理函数类型

接下来定义一个通用类型,约束每个处理函数必须接收对应DataType的数据:

// 通用处理函数类型:接收对应DataType的数据,返回void
type DataHandler<T extends DataType> = (data: DataMap[T]) => void;

步骤3:创建类型安全的函数映射表

现在创建映射表时,通过Record类型约束键为DataType,值为对应类型的处理函数,确保映射关系完全匹配:

// 对应的保存函数(保持原定义)
const saveDataA = (data: DataA) => { /* 实现逻辑 */ };
const saveDataB = (data: DataB) => { /* 实现逻辑 */ };

const saveFuncMap: Record<DataType, DataHandler<DataType>> = {
    [DataType.A]: saveDataA,
    [DataType.B]: saveDataB,
};

步骤4:实现类型安全的统一入口函数

最后,用泛型函数实现统一入口,利用data.type作为泛型参数,让TypeScript自动推导并收窄类型:

const saveData = <T extends DataType>(data: DataMap[T]) => {
    return saveFuncMap[data.type](data as DataMap[T]);
};

扩展性说明

  • 新增DataType.C和DataC时,只需:
    1. 在DataType枚举中添加C = 'C'
    2. 定义DataC接口
    3. 在DataMap中添加[DataType.C]: DataC
    4. 实现saveDataC并添加到saveFuncMap
  • 对于updateData、deleteData等其他操作,只需复制这套模式:创建对应的updateFuncMap、deleteFuncMap,复用DataMap和DataHandler类型即可,无需重复编写switch逻辑。

类型检查验证

调用saveData时,TypeScript会自动校验参数类型:

// 正确:符合DataA类型
saveData({ id: 1, type: DataType.A, fieldA: 'test' });

// 错误:fieldA缺失,TypeScript会提示类型错误
saveData({ id: 1, type: DataType.A });

// 错误:type为A但传入了fieldB,TypeScript会提示类型错误
saveData({ id: 1, type: DataType.A, fieldB: 'test' });

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.07.14 10:02:45