TypeScript如何根据传入枚举参数类型校验另一个配置参数结构
实现方案
你可以通过函数重载或者泛型映射类型两种方式实现参数关联校验,两种方案都能让TS自动根据你传入的枚举值校验config的结构:
前置准备
先为每个枚举值定义对应的专属配置类型:
// Trellis类型对应的配置结构,可按需增删字段 interface TrellisConfig { rowCount?: number background?: string } // Divot类型对应的配置结构,强制要求padding字段 interface DivotConfig { padding: number gap?: number } // 你原有的枚举定义 export enum TemplateFill { Trellis = "Trellis", Divot = "Divot" }
方案1:函数重载(直观易读)
直接为不同枚举值的入参声明对应的重载签名即可:
// 重载1:type为Trellis时,config匹配TrellisConfig export declare function FactoryTemplateFill( type: TemplateFill.Trellis, config: TrellisConfig ): HTMLCanvasElement | undefined // 重载2:type为Divot时,config匹配DivotConfig export declare function FactoryTemplateFill( type: TemplateFill.Divot, config: DivotConfig ): HTMLCanvasElement | undefined // 实际函数实现的兼容签名 export function FactoryTemplateFill( type: TemplateFill, config: TrellisConfig | DivotConfig ) { // 业务逻辑里TS会自动收窄类型 if (type === TemplateFill.Divot) { // 此处TS可自动识别config为DivotConfig,调用padding无类型报错 console.log(config.padding) } // 剩余实现逻辑... return undefined }
校验效果
// ✅ 合法调用 FactoryTemplateFill(TemplateFill.Divot, { padding: 12 }) FactoryTemplateFill(TemplateFill.Trellis, { rowCount: 5 }) // ❌ TS直接报错:Divot类型的config缺少必填字段padding FactoryTemplateFill(TemplateFill.Divot, { gap: 8 })
方案2:泛型映射类型(扩展性强)
如果后续需要频繁新增枚举值,用映射类型关联枚举和配置,不用每次修改函数签名:
// 定义枚举到配置类型的映射关系 type TemplateConfigMap = { [TemplateFill.Trellis]: TrellisConfig [TemplateFill.Divot]: DivotConfig } // 用泛型约束自动关联入参类型 export declare function FactoryTemplateFill<T extends TemplateFill>( type: T, config: TemplateConfigMap[T] ): HTMLCanvasElement | undefined // 函数实现和方案1一致即可
后续新增枚举值时,只需要在TemplateConfigMap里新增对应的配置类型映射即可,无需调整函数定义。
内容的提问来源于stack exchange,提问作者user15361861
相关产品推荐
相关产品推荐

