如何在TypeScript映射类型中实现函数参数的严格类型校验?
给动态调用的函数加上类型安全校验
你现在的问题是通过callFunction调用时没有类型检查,同时还要保留添加新函数时自动提示补全映射的特性,直接按下面的方式修改即可:
优化映射类型的定义
把原来用any的FunctionMap改成关联具体类型的版本,让每个type对应的函数签名和原函数完全对齐:
type AllFunctions = FuncAOptions | FuncBOptions // 替换原有FunctionMap,每个type对应正确的参数和返回值类型 type FunctionMap = { [K in AllFunctions['type']]: ( options: Extract<AllFunctions, { type: K }> ) => ReturnType<typeof funcA | typeof funcB> extends infer R ? R : never }
这里用Extract<AllFunctions, { type: K }>精准提取对应type的options类型,彻底避免any导致的类型丢失问题。
将callFunction改为泛型函数
用泛型绑定type参数和options的关联关系,让TypeScript能根据传入的type自动校验参数:
function callFunction<T extends keyof FunctionMap>( type: T, options: Parameters<FunctionMap[T]>[0] ): ReturnType<FunctionMap[T]> { return functionMap[type](options) }
Parameters和ReturnType是TypeScript自带的工具类型,分别用来提取函数的参数类型和返回值类型,这样callFunction的参数校验、返回值推导就和直接调用原函数完全一致。
完整代码示例
type FuncAOptions = { type: 'A' opt1: string opt2: boolean } function funcA(options: FuncAOptions): number { if (!options.opt1) throw new Error('Missing required option') return 1 } type FuncBOptions = { type: 'B' opt3: number opt4: (a: number) => number } function funcB(options: FuncBOptions): string { if (!options.opt3) throw new Error('Missing required option') return 'B' } type AllFunctions = FuncAOptions | FuncBOptions type FunctionMap = { [K in AllFunctions['type']]: ( options: Extract<AllFunctions, { type: K }> ) => ReturnType<typeof funcA | typeof funcB> extends infer R ? R : never } const functionMap: FunctionMap = { A: funcA, B: funcB } function callFunction<T extends keyof FunctionMap>( type: T, options: Parameters<FunctionMap[T]>[0] ): ReturnType<FunctionMap[T]> { return functionMap[type](options) } // 合法调用,类型校验通过 callFunction('A', { type: 'A', opt1: 'demo', opt2: false }) callFunction('B', { type: 'B', opt3: 456, opt4: num => num + 10 }) // 非法调用,会触发TypeScript报错 callFunction('A', { type: 'B', opt3: 'oops' }) // 参数类型不匹配 callFunction('B', { type: 'B', opt3: 'not a number' }) // opt3必须是number类型
关键特性保留
- 严格类型校验:现在调用
callFunction时,参数会像直接调用原函数一样被严格校验,传错参数或类型会立刻触发TypeScript报错。 - 自动补全提示:如果以后给
AllFunctions添加新的options类型(比如FuncCOptions),TypeScript会马上提示你要给functionMap加上对应的键值对,不会出现遗漏。
内容的提问来源于stack exchange,提问作者seancdavis
相关产品推荐
相关产品推荐

