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
相关产品推荐
相关产品推荐

