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

如何在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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.07.20 01:22:48