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

TypeScript中基于Tag配置创建泛型类型约束的实现方案

解决方案

先明确基础类型定义(基于你描述的现有代码结构):

// 现有枚举与配置类型
enum Tag {
  STANDARD = 'standard',
  UV_RANGE = 'uvRange',
  TEMP_RANGE = 'tempRange',
  CUSTOM = 'custom'
}

enum DataType {
  NUMBER = 'number',
  TIME_RANGE = 'timeRange',
  STRING = 'string'
}

interface CommonTagDataConfig {
  dataType: DataType.NUMBER | DataType.STRING;
  defaultValue: number | string;
}

interface TimeRangeDataConfig {
  dataType: DataType.TIME_RANGE;
  range: [Date, Date];
}

type TagDataConfig = CommonTagDataConfig | TimeRangeDataConfig;

// 标签-配置映射表
const TagConfigurations: Record<Tag, TagDataConfig> = {
  [Tag.STANDARD]: { dataType: DataType.NUMBER, defaultValue: 0 },
  [Tag.UV_RANGE]: { dataType: DataType.TIME_RANGE, range: [new Date(), new Date()] },
  [Tag.TEMP_RANGE]: { dataType: DataType.TIME_RANGE, range: [new Date(), new Date()] },
  [Tag.CUSTOM]: { dataType: DataType.STRING, defaultValue: '' }
};

实现泛型约束类型

1. TagForConfig<T>:根据配置类型筛选标签

这个泛型会从TagConfigurations中提取所有对应配置类型为T的Tag枚举值:

type TagForConfig<T extends TagDataConfig> = {
  [K in keyof typeof TagConfigurations]: typeof TagConfigurations[K] extends T ? K : never;
}[keyof typeof TagConfigurations];

2. TagForType<T>:根据DataType筛选标签

这个泛型会提取所有TagConfigurations中dataType字段匹配T的Tag枚举值:

type TagForType<T extends DataType> = {
  [K in keyof typeof TagConfigurations]: typeof TagConfigurations[K]['dataType'] extends T ? K : never;
}[keyof typeof TagConfigurations];

在组件Props中使用约束

基于配置类型约束组件

interface TimeRangeTagProps {
  // 只允许传入对应TimeRangeDataConfig的Tag
  tag: TagForConfig<TimeRangeDataConfig>;
}

const TimeRangeTag = ({ tag }: TimeRangeTagProps) => {
  return <div>Time Range Tag: {tag}</div>;
};

// 合法:UV_RANGE对应TimeRangeDataConfig
<TimeRangeTag tag={Tag.UV_RANGE} />

// 类型报错:STANDARD对应CommonTagDataConfig,不符合约束
// <TimeRangeTag tag={Tag.STANDARD} />

基于DataType约束组件

interface TimeTypeTagProps {
  // 只允许传入dataType为TIME_RANGE的Tag
  tag: TagForType<DataType.TIME_RANGE>;
}

const TimeTypeTag = ({ tag }: TimeTypeTagProps) => {
  return <div>Time Type Tag: {tag}</div>;
};

// 合法:TEMP_RANGE的dataType是TIME_RANGE
<TimeTypeTag tag={Tag.TEMP_RANGE} />

// 类型报错:CUSTOM的dataType是STRING,不符合约束
// <TimeTypeTag tag={Tag.CUSTOM} />

原理说明

这两个泛型通过映射类型遍历TagConfigurations的所有键,用条件类型判断当前键对应的配置是否匹配目标类型,最后通过[keyof typeof TagConfigurations]将所有符合条件的键合并为联合类型。整个校验在编译期完成,完全替代了运行时类型守卫,避开了React Hooks对条件判断的限制。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.08.06 02:45:32