如何按对象键定义函数参数类型?求TypeScript类型定义帮助
解决TypeScript中根据路径自动校验函数参数的类型问题
我来帮你搞定这个类型定义的问题!你的核心需求是让getConfig根据传入的不同路径,自动校验参数的必填性和结构正确性对吧?我们一步步来修正你的代码:
首先先看原代码里的两个关键问题:
- 原
ConfigArgs的类型没有正确处理无参数函数的情况,导致无参数路径也能传参而不报错; getConfig的泛型参数和参数定义没有正确关联路径与对应的参数类型,无法实现自动校验。
修正后的完整代码
const path = { A: 'home', B: 'support', C: 'contact' } as const type B = unknown const B: B = {}; const config = { [path.A]: () => null, [path.B]: (): B => B, [path.C]: ({ active, }: { active: boolean }) => B, } as const type Config = typeof config // 正确提取每个路径对应的函数参数类型:无参数则设为never type ConfigArgs = { [P in keyof Config]: Config[P] extends (...args: infer A) => any ? A extends [] ? never // 无参数的函数,禁止传递任何参数 : A[0] // 单参数函数,提取参数的类型 : never } // 修正后的getConfig:自动关联路径与参数类型,精准校验 function getConfig<P extends keyof Config>( path: P, ...args: ConfigArgs[P] extends never ? [] : [ConfigArgs[P]] ): ReturnType<Config[P]> { return config[path](...args as any) } // 测试用例完全符合你的期望: getConfig(path.A) // ✅ 无错误 getConfig(path.C, {active:true}) // ✅ 无错误 getConfig(path.C, {id:"xxx"}) // ❌ 类型错误:不存在id属性 getConfig(path.C) // ❌ 类型错误:缺少必填参数 getConfig(path.A, {active:true}) // ❌ 类型错误:不能传递参数 getConfig(path.B) // ✅ 无错误(path.B的函数无参数)
关键部分解释
1. 修正ConfigArgs类型
- 用
(...args: infer A)提取函数的所有参数数组,而不是单个参数,这样能覆盖无参数的场景; - 判断参数数组是否为空:如果是空数组(
A extends []),说明函数不需要参数,对应的ConfigArgs[P]设为never,后续就能禁止传参; - 如果有参数,取数组的第一个元素
A[0](因为你的所有函数都是0个或1个参数,要是有多参数需求,直接改成A即可)。
2. 修正getConfig函数
- 泛型
P extends keyof Config明确路径只能是config的合法键,也就是path对象里的三个值; - 参数部分用条件类型处理必填/可选:当
ConfigArgs[P]是never(无参数函数),要求args是空数组,不能传参;当有参数类型时,要求必须传递对应结构的参数; - 返回值用
ReturnType<Config[P]>自动推导每个路径的函数返回值,比原来的B | null更精准。
扩展:支持多参数函数
如果后续需要支持多参数的函数,只需要微调类型定义即可:
// 新增一个多参数的路径 const path = { // ...原有路径 D: 'detail' } as const const config = { // ...原有配置 [path.D]: (id: string, isEdit: boolean) => ({ id, isEdit }) } as const // 调整ConfigArgs为直接提取参数数组 type ConfigArgs = { [P in keyof Config]: Config[P] extends (...args: infer A) => any ? A : never } // 调整getConfig的参数部分 function getConfig<P extends keyof Config>( path: P, ...args: ConfigArgs[P] ): ReturnType<Config[P]> { return config[path](...args as any) } // 调用示例: getConfig(path.D, '123', true) // ✅ 无错误 getConfig(path.D, '123') // ❌ 类型错误:缺少第二个参数
内容的提问来源于stack exchange,提问作者Leigh Cheri
相关产品推荐
相关产品推荐

