使用泛型实现多API调用函数强类型的TypeScript问题
解决TypeScript多API函数的强类型约束问题
问题分析
你当前的RouteParams类型报错,核心原因是TypeScript无法确认泛型R是对应APIA的合法路由——尽管execute函数的调用能正常提供类型提示,但类型定义本身存在索引不匹配的逻辑漏洞。
解决方案
重构类型定义,通过一个统一的API配置类型来关联API名称、路由和参数,让TypeScript能正确推导各类型间的依赖关系:
步骤1:定义统一的API配置数据源
先创建一个包含所有API、路由及对应参数的主类型,作为所有子类型的唯一数据源:
type APIDefinitions = { google: { endpoint1: { name: string }; endpoint2: { otherName: string }; }; yahoo: { endpoint3: { otherOtherName: string }; }; };
步骤2:从主类型自动推导子类型
基于APIDefinitions自动生成API名称、路由和参数类型,避免手动维护分散的联合类型:
// API名称的联合类型 type APINames = keyof APIDefinitions; // 指定API对应的路由联合类型 type Routes<A extends APINames> = keyof APIDefinitions[A]; // 指定API+路由组合对应的参数类型 type RouteParams<A extends APINames, R extends Routes<A>> = APIDefinitions[A][R];
步骤3:定义强类型的execute函数
函数的泛型约束会自动关联三个参数的类型,确保参数组合的合法性:
const execute = <A extends APINames, R extends Routes<A>>( api: A, route: R, params: RouteParams<A, R> ) => { // 此处编写API调用逻辑 };
验证调用效果
调用时TypeScript会自动校验参数匹配性,错误参数会直接触发类型报错:
// 合法调用:google的endpoint1要求传入name参数 execute('google', 'endpoint1', { name: 'George Washington' }); // 错误调用:google的endpoint2不接受name参数,会提示类型错误 execute('google', 'endpoint2', { name: 'Invalid Param' });
替代方案:参数元组推断(更简洁)
如果不想手动指定泛型,可以用TypeScript的参数元组推断让类型自动推导:
const execute = <T extends keyof APIDefinitions, U extends keyof APIDefinitions[T]>( ...args: [api: T, route: U, params: APIDefinitions[T][U]] ) => { // 此处编写API调用逻辑 };
这种写法和之前的效果完全一致,但代码更紧凑。
内容的提问来源于stack exchange,提问作者dinx
相关产品推荐
相关产品推荐

