如何实现带类型安全的参数化URL查找函数?
解决方案
核心思路是利用TypeScript的类型推导能力,从你已有的URLS对象自动提取路由名称和参数类型,避免重复维护多个结构,同时保留完整的类型安全性。
实现代码
// 保留你现有URLS结构,无需额外修改 const URLS = { dashboard: { createPath: ({ accountNumber }: { accountNumber: string }) => `/account/${accountNumber}` }, property: { createPath: ({ accountNumber, propertyId }: { accountNumber: string, propertyId: string }) => `/account/${accountNumber}/property/${propertyId}` } } // 自动推导所有路由名称的联合类型 type RouteName = keyof typeof URLS; // 自动推导对应路由所需的参数类型 type RouteParams<T extends RouteName> = Parameters<typeof URLS[T]['createPath']>[0]; // 实现getUrl函数,完全基于URLS的类型自动约束 function getUrl<T extends RouteName>(routeName: T, params: RouteParams<T>): string { return URLS[routeName].createPath(params); }
使用示例
// 类型安全的调用,参数不匹配会直接报错 const dashboardUrl = getUrl('dashboard', { accountNumber: 'ABC123' }); const propertyUrl = getUrl('property', { accountNumber: 'ABC123', propertyId: 'PROP456' }); // 错误示例:参数缺失/错误会触发TypeScript编译错误 // getUrl('dashboard', { propertyId: 'PROP456' }); // getUrl('invalidRoute', {});
方案优势
- 单一数据源:仅需维护
URLS一个对象,新增/修改路由时只需更新此处,无需同步修改其他类型或函数 - 完整类型安全:路由名称错误、参数缺失/类型不匹配都会在编译阶段被捕获,避免运行时错误
- 调用简洁:完全符合你期望的
getUrl(路由名, 参数对象)调用方式,替换现有代码成本极低
扩展支持无参数路由
如果需要支持无参数的路由,只需调整getUrl函数的参数可选性即可:
function getUrl<T extends RouteName>(routeName: T, params?: RouteParams<T>): string { return URLS[routeName].createPath(params as RouteParams<T>); } // 添加无参数路由 const URLS = { // ... 现有路由 home: { createPath: () => '/' } } // 简洁调用 const homeUrl = getUrl('home');
内容的提问来源于stack exchange,提问作者Gilly Ames
相关产品推荐
相关产品推荐

