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

React TypeScript:如何兼顾获取枚举类型与传递只读对象作为Props

问题描述

我有如下数据:

const ActionData = [
  { label: 'Edit', icon: 'pen', key: 'edit' },
  { label: 'Skip', icon: 'forward', key: 'skip' },
  { label: 'Stop', icon: 'stop-circle', key: 'stop' },
];

用它来渲染ActionItem组件列表:

{ActionData.map((dataItem) => (
        <ActionItem 
          key={dataItem.key}
          item={dataItem} 
          onPress={handleActionClick} 
        />
))}

我需要一个类型ActionItemKeyType,其值应为'edit' | 'skip' | 'stop',也就是ActionData的key值集合。

如果把ActionData声明为只读数组:

const ActionData = [
  { label: 'Edit', icon: 'pen', key: 'edit' },
  { label: 'Skip', icon: 'forward', key: 'skip' },
  { label: 'Stop', icon: 'stop-circle', key: 'stop' },
] as const;

就能通过以下代码得到预期的ActionItemKeyType:

type ActionItemKeyType = typeof ActionData[number]['key'];

但这样声明后数组变为只读,渲染时无法将item作为Props传递。请问如何同时实现提取精确key类型和数组可用于组件Props传递这两个功能?

解决方案

方法一:先定义只读数组提取类型,再创建可变副本

先通过as const声明只读数组来提取类型,再用扩展运算符创建可变数组副本用于渲染:

// 只读数组,仅用于提取类型
const _ActionData = [
  { label: 'Edit', icon: 'pen', key: 'edit' },
  { label: 'Skip', icon: 'forward', key: 'skip' },
  { label: 'Stop', icon: 'stop-circle', key: 'stop' },
] as const;

// 提取目标key类型
type ActionItemKeyType = typeof _ActionData[number]['key'];

// 创建可变数组,用于组件渲染
const ActionData = [..._ActionData];

这样ActionData是可变数组,可正常传递给组件Props,同时ActionItemKeyType能精确得到'edit' | 'skip' | 'stop'的联合类型。

方法二:先定义基础类型,再推导数组和key类型

先定义单个数据项的类型,再基于此推导数组类型和key类型,同时保证数组可变性:

// 定义单个动作项的类型,明确key的可选值
type ActionItem = {
  label: string;
  icon: string;
  key: 'edit' | 'skip' | 'stop';
};

// 声明可变数组,类型约束为ActionItem[]
const ActionData: ActionItem[] = [
  { label: 'Edit', icon: 'pen', key: 'edit' },
  { label: 'Skip', icon: 'forward', key: 'skip' },
  { label: 'Stop', icon: 'stop-circle', key: 'stop' },
];

// 提取key类型
type ActionItemKeyType = ActionItem['key'];

这种方法逻辑直接,但需要手动维护ActionItem中的key联合类型,后续新增动作项时需同步更新类型定义和数组内容。

方法三:类型断言解除只读限制(谨慎使用)

如果不想创建数组副本,可在传递Props时用类型断言解除单个item的只读限制:

const ActionData = [
  { label: 'Edit', icon: 'pen', key: 'edit' },
  { label: 'Skip', icon: 'forward', key: 'skip' },
  { label: 'Stop', icon: 'stop-circle', key: 'stop' },
] as const;

type ActionItemKeyType = typeof ActionData[number]['key'];

// 渲染时断言item为非只读类型
{ActionData.map((dataItem) => (
  <ActionItem 
    key={dataItem.key}
    item={dataItem as Omit<typeof dataItem, never>} 
    onPress={handleActionClick} 
  />
))}

注意:此方法会绕过TypeScript的只读检查,若组件Props会修改item内容,可能引发意外问题,仅在确定组件不会修改item时使用。

内容的提问来源于stack exchange,提问作者kashif-sk

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.07.29 21:13:24