TypeScript字段类型依赖另一字段类型 如何避免高阶类型m*n联合冗余
解决方案
你可以通过类型映射+泛型提取关联类型的方式实现,只需要分别定义基础类型、高阶类型两类结构,无需写m*n的全量组合。
步骤1:定义基础类型映射与工具方法
// 基础类型kind和对应原始值的映射表:新增基础类型仅需在这里加一条记录 type PrimitiveKindMap = { number: number string: string } // 通用工具:根据类型模式(type/typedValue)返回对应值类型 type GetValueFromKind<K extends keyof PrimitiveKindMap, T extends 'type' | 'typedValue'> = T extends 'type' ? undefined : PrimitiveKindMap[K]
步骤2:改写基础数据类型定义
type _DataType<T extends 'type' | 'typedValue', K extends keyof PrimitiveKindMap = keyof PrimitiveKindMap> = K extends any ? { kind: K value: GetValueFromKind<K, T> } : never // 保持原有类型别名不变,功能完全兼容 type DataType = _DataType<'type'> type TypedValue = _DataType<'typedValue'>
步骤3:定义高阶类型
// 高阶类型枚举:新增高阶类型仅需在这里加kind type HigherKind = 'Array' | 'Single' | 'Option' | 'Set' // 高阶类型包装逻辑:新增高阶类型仅需在这里加对应包装规则 type WrapValue<RawValue, H extends HigherKind> = H extends 'Array' ? RawValue[] : H extends 'Set' ? Set<RawValue> : H extends 'Option' ? RawValue | null : H extends 'Single' ? RawValue : never // 最终高阶类型定义,自动生成所有组合变体 type _HigherType<T extends 'type' | 'typedValue', H extends HigherKind = HigherKind, K extends keyof PrimitiveKindMap = keyof PrimitiveKindMap> = H extends any ? K extends any ? { kind: H t: _DataType<'type', K> value: T extends 'type' ? undefined : WrapValue<PrimitiveKindMap[K], H> } : never : never // 保持原有类型别名不变 type HigherType = _HigherType<'type'> type HigherTypedValue = _HigherType<'typedValue'>
核心原理
利用TS的分配条件类型特性,当泛型参数是联合类型时,条件类型会自动遍历每个联合成员生成对应的类型变体,自动完成m种基础类型和n种高阶类型的组合,完全避免重复代码。
内容的提问来源于stack exchange,提问作者user2925565
相关产品推荐
相关产品推荐

