TypeScript如何根据request方法首个SDK模块参数校验第二个方法参数
最优实现方案
不用写大量方法重载,只需要维护一份模块-方法映射即可,类型会自动关联推导,后续新增/修改模块和方法只需要改一处配置,维护成本极低。
步骤1:定义模块方法映射常量
首先将所有模块对应的方法列表定义为const类型,让TypeScript可以提取到精确的字面量类型,而不是宽化为string[]:
const MODULE_METHODS = { orders: ['getOrder', 'getOrderExt', 'getOrderItems', 'saveOrders'], pricing: ["getCompetitivePricing", "getItemOffers", "getListingOffers", "getPricing"], catalogV2: ["getCatalogItem", "searchCatalogItems", "getCatalogProdType"], catalog: [], prodType: [], reports: [], listings: [] } as const;
步骤2:提取关联类型
基于上面的常量自动生成需要的工具类型,不需要手动维护枚举:
// 自动生成SDK模块联合类型,新增模块时不需要手动修改 export type SDKmodules = keyof typeof MODULE_METHODS; // 泛型工具:传入模块名,返回对应模块允许的方法联合类型 type MethodForModule<T extends SDKmodules> = typeof MODULE_METHODS[T][number];
步骤3:改造request方法增加泛型约束
给request方法增加泛型参数,把第一个参数mod和第二个参数method的类型做关联绑定:
export class SellerAPI { // 这里http的定义你自己保留原来的即可,我这里加个声明避免TS报错 private http = { get: <T>(url: string, opts: any) => Promise.resolve<T>({} as T) } request<T extends SDKmodules>(mod: T, method: MethodForModule<T>, params: any = {}) { return this.http.get<any>(`/sp-sdk/${mod}/${method}`, { params }); } }
效果验证
调用时TypeScript会自动根据你传入的第一个参数,限制第二个参数的可选值,传错直接报错:
const api = new SellerAPI(); // 合法调用,无报错 api.request('orders', 'getOrder'); api.request('pricing', 'getCompetitivePricing'); // 非法调用,TS直接提示类型错误:类型"getCompetitivePricing"的参数不能赋给类型"getOrder" | "getOrderExt" | "getOrderItems" | "saveOrders"的参数 api.request('orders', 'getCompetitivePricing');
扩展建议
如果后续需要同时约束params参数类型和接口返回值类型,只需要把MODULE_METHODS的结构扩展为方法对应入参出参的格式即可,不需要改动其他逻辑。
内容的提问来源于stack exchange,提问作者Omar
相关产品推荐
相关产品推荐

