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

如何在TypeScript中根据泛型属性选择对应类型?

如何根据泛型属性选择类型?

问题场景

现有如下TypeScript代码,所有动物对象都包含type属性(对应AnimalType枚举),其余属性因种类而异。需要实现一个泛型类型Animal<T>,使得Animal<AnimalType.DOG>等价于typeof dog,但当前嵌套条件类型的实现过于冗长:

enum AnimalType {
  DOG,
  CAT,
  FROG,
  SNAKE,
}

const dog = {
  type: AnimalType.DOG,
  legs: 4,
}

const cat = {
  type: AnimalType.CAT,
  tail: 1,
}

const frog = {
  type: AnimalType.FROG,
  canSwim: true,
  tail: 0,
}

const snake = {
  type: AnimalType.SNAKE,
  tail: 'looong',
  age: 2,
}

// 现有冗长实现
type Animal<T extends AnimalType> = T extends AnimalType.DOG ? typeof dog : T extends AnimalType.CAT ? typeof cat : T extends AnimalType.FROG ? typeof frog : T extends AnimalType.SNAKE ? typeof snake : unknown

更优解决方案

方案一:利用内置Extract工具类型

先定义所有动物的联合类型,再通过Extract筛选出对应type属性的成员:

// 定义所有动物的联合类型
type AllAnimals = typeof dog | typeof cat | typeof frog | typeof snake;

// 提取type属性等于T的动物类型
type Animal<T extends AnimalType> = Extract<AllAnimals, { type: T }>;

说明:Extract是TypeScript内置工具类型,作用是从第一个联合类型参数中,提取出可赋值给第二个类型参数的成员。这里通过{ type: T }作为筛选条件,精准匹配对应枚举值的动物类型。

方案二:构建枚举-类型映射表

直接创建一个以枚举值为键、对应动物类型为值的映射类型,通过索引访问获取目标类型:

// 构建枚举到类型的映射表
type AnimalMap = {
  [AnimalType.DOG]: typeof dog;
  [AnimalType.CAT]: typeof cat;
  [AnimalType.FROG]: typeof frog;
  [AnimalType.SNAKE]: typeof snake;
};

// 通过索引访问获取对应类型
type Animal<T extends AnimalType> = AnimalMap[T];

说明:这种方式逻辑直观,维护成本低——新增动物种类时,只需在AnimalMap中添加一行键值对即可,可读性更强。

验证效果

两种方案都能实现预期效果:

// 类型等价于typeof dog
type DogType = Animal<AnimalType.DOG>;
// 类型等价于typeof snake
type SnakeType = Animal<AnimalType.SNAKE>;

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.07.03 10:16:07