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

如何用泛型推断对象值类型?TypeScript类型安全难题

解决方案

要同时实现枚举成员全覆盖的类型安全和函数参数类型的精确推断,可以通过「泛型约束 + as const/泛型工厂函数」的组合来实现,核心是既要约束对象必须包含所有枚举键,又要保留每个函数的具体参数类型信息,避免被索引签名抹平。

方法一:使用 satisfies 关键字(TypeScript 4.9+)

这种方式最简洁,无需额外工具函数:

  1. 定义枚举和约束类型
export enum Enum {
    A,
    B,
    C,
}

// 约束类型:必须包含所有 Enum 成员,且每个值都是返回 string 的函数
type EnumFunctionMap = Record<Enum, (...args: any[]) => string>;
  1. 定义对象并添加约束
export const obj = {
    [Enum.A]: () => 'example 1',
    [Enum.B]: (arg1: string) => 'example 2, arg1: %s',
    [Enum.C]: (nr: string, arg2: string) => 'example %s %s',
} as const satisfies EnumFunctionMap;
  • as const:保留每个函数的具体参数类型,避免被自动拓宽为 any[];
  • satisfies EnumFunctionMap:强制检查对象是否包含所有枚举成员,少写任何一个枚举键都会触发类型报错。
  1. 定义类型安全的工具函数
const fct = <E extends keyof typeof obj>(
    code: E,
    ...args: Parameters<(typeof obj)[E]>
) => {
    const template = obj[code](...args);
    // 可在此添加字符串格式化逻辑(比如替换 %s)
    return template;
};

调用 fct 时:

  • code 只能传入 Enum 的有效值;
  • args 类型会根据 code 自动推断:比如传 Enum.A 无需参数,传 Enum.C 必须传两个字符串参数。

方法二:使用泛型工厂函数(兼容低版本 TypeScript)

如果项目使用 TypeScript 4.9 以下版本,可通过泛型函数实现相同效果:

export enum Enum {
    A,
    B,
    C,
}

// 泛型工厂函数,约束输入对象必须包含所有枚举成员,同时保留具体函数类型
function createEnumMap<T extends Record<Enum, (...args: any[]) => string>>(map: T): T {
    return map;
}

// 生成类型安全的对象
export const obj = createEnumMap({
    [Enum.A]: () => 'example 1',
    [Enum.B]: (arg1: string) => 'example 2, arg1: %s',
    [Enum.C]: (nr: string, arg2: string) => 'example %s %s',
});

// 工具函数定义和方法一完全一致
const fct = <E extends keyof typeof obj>(
    code: E,
    ...args: Parameters<(typeof obj)[E]>
) => {
    const template = obj[code](...args);
    return template;
};

为什么之前的方案失效?

你尝试的 { [key in Enum]: (...args: any[]) => string } 是同构映射类型,会把所有函数的参数类型统一为 any[],丢失了每个函数的具体参数信息。而上面的方案通过泛型推断保留了每个函数的原始参数类型,同时通过 Record<Enum, ...> 确保了枚举成员的全覆盖。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.07.12 05:25:16