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

React TypeScript项目中如何用枚举替代联合类型作为对象键?

可以用枚举作为templates的键,具体实现如下

1. 定义绑定枚举的模板映射类型

先创建基于TeaserTypeName枚举的模板类型,让每个枚举值对应专属的处理函数类型:

import React from 'react';

// 假设已定义以下类型
type ItemOneType = { id: string; /* 其他属性 */ };
type ItemTwoType = { uuid: string; /* 其他属性 */ };

export enum TeaserTypeName {
  TypeOne = 'TypeOne',
  TypeTwo = 'TypeTwo',
}

// 基于枚举的模板映射类型
type TemplateMap = {
  [K in TeaserTypeName]: {
    expanded: (item: K extends TeaserTypeName.TypeOne ? ItemOneType : ItemTwoType) => React.ReactNode;
  };
};

2. 重构templates对象,使用枚举作为键

将原字符串键替换为枚举值,同时指定类型为TemplateMap,确保类型严格匹配:

const templates: TemplateMap = {
  [TeaserTypeName.TypeOne]: {
    expanded: (typeOne: ItemOneType) => <ItemOne key={typeOne.id} {...typeOne} />,
  },
  [TeaserTypeName.TypeTwo]: {
    expanded: (typeTwo: ItemTwoType) => <ItemTwo key={typeTwo.uuid} {...typeTwo} />,
  },
};

3. 定义items的判别联合类型

给items数组定义判别联合类型,让TypeScript能通过type字段自动推断item的具体结构:

type Item = 
  | ({ type: TeaserTypeName.TypeOne } & ItemOneType)
  | ({ type: TeaserTypeName.TypeTwo } & ItemTwoType);

// 示例items数组
const items: Item[] = [
  { type: TeaserTypeName.TypeOne, id: '1', /* ItemOneType其他属性 */ },
  { type: TeaserTypeName.TypeTwo, uuid: '2', /* ItemTwoType其他属性 */ },
];

4. 遍历渲染,无需any断言

现在遍历items时,TypeScript会自动根据item.type匹配对应模板函数,彻底摆脱any断言:

<ul>
  {items.map((item) => {
    return templates[item.type].expanded(item);
  })}
</ul>

核心优势

  • 类型安全:避免字符串拼写错误,编译阶段就能检查键的合法性
  • 自动推导:通过判别联合类型,TypeScript能自动识别item的具体类型
  • 易扩展:后续新增类型时,只需在枚举和模板中添加对应项,TypeScript会自动提示类型补全

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.07.11 12:17:18