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

TypeScript中基于枚举键的工厂函数类型推断优化问询

解决TypeScript工厂函数的类型标注问题

要同时实现switch分支内payload类型验证和调用时精确的返回类型推断,最优雅的方式是使用函数重载,它能完美匹配你的需求。下面是具体的实现方案:

完整代码示例

首先保留你定义的枚举、接口和类型:

enum keys { key1 = 1, key2 = 2 }

interface Test1 { key: keys.key1; payload: string; }
interface Test2 { key: keys.key2; payload: number; }

type tests = Test1 | Test2;

interface ReturnTypeOfTest1 { returnedObject1: number; }
interface ReturnTypeOfTest2 { returnedObject2: string; }

interface ModelOfTest { 
  [keys.key1]: ReturnTypeOfTest1; 
  [keys.key2]: ReturnTypeOfTest2; 
}

实现正确类型标注的工厂函数

// 重载签名:明确每个输入类型对应的精确返回类型
function getTest(t: Test1): ReturnTypeOfTest1;
function getTest(t: Test2): ReturnTypeOfTest2;

// 实现签名:处理联合类型输入,内部通过switch窄化类型
function getTest(t: tests): ModelOfTest[keys] {
  switch (t.key) {
    case keys.key1: {
      const data = t.payload; // 类型自动推断为string ✅
      return { returnedObject1: 123 }; // 类型检查符合ReturnTypeOfTest1 ✅
    }
    case keys.key2: {
      const data = t.payload; // 类型自动推断为number ✅
      return { returnedObject2: '123' }; // 类型检查符合ReturnTypeOfTest2 ✅
    }
    default:
      // 兜底处理未知枚举键,避免编译错误
      throw new Error(`Unsupported key: ${t.key}`);
  }
}

调用效果验证

调用时TypeScript会自动推断精确的返回类型,同时严格检查payload的类型:

// 返回类型为ReturnTypeOfTest1,payload必须是string
const res1 = getTest({ key: keys.key1, payload: 'hello' });
console.log(res1.returnedObject1); // 类型安全,不会提示不存在的属性

// 返回类型为ReturnTypeOfTest2,payload必须是number
const res2 = getTest({ key: keys.key2, payload: 456 });
console.log(res2.returnedObject2); // 同样类型安全

为什么之前的写法有缺陷?

  • 第一种写法:用tests作为参数类型时,switch分支能通过key窄化参数类型,所以payload类型正确,但返回类型用any或联合类型,丢失了调用时的精确类型推断。
  • 第二种写法:泛型T extends tests虽然能让返回类型精确,但TypeScript无法在泛型函数的switch分支内将泛型T窄化到具体的Test1或Test2,导致payload类型变成联合类型,返回值也要求符合所有可能返回类型的交集,从而报错。

而函数重载通过明确的输入输出类型映射,既满足了内部分支的类型验证,又保证了外部调用的精确类型推断。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.05.14 09:02:27