TypeScript中如何基于接口修改属性为生成的Proxy对象定义类型
可以实现,需要用到 TypeScript 4.1 及以上版本支持的模板字面量类型和映射类型键重映射特性,具体实现如下:
基础实现
直接使用 TS 内置的 Capitalize 工具类型处理路由名的首字母大写,再通过键重映射生成对应的方法名:
type ProxedRouteMap<T> = { // 生成 get[路由名]Url 方法,返回拼接好的路由字符串 [P in keyof T as `get${Capitalize<P & string>}Url`]: (params?: Record<string, string | number>) => string; } & { // 生成 goTo[路由名]Url 方法,直接跳转对应路由 [P in keyof T as `goTo${Capitalize<P & string>}Url`]: (params?: Record<string, string | number>) => void; } & { // 此处可扩展其他通用模板方法的类型定义 commonJump: (fullPath: string) => void; getRawRoute: (routeKey: keyof T) => string; }
使用示例
export interface RouteMap { routeA: string; routeB: string; routeC: string; } const routesMap: RouteMap = { routeA: 'route-a-url', routeB: 'route-b-url/:param', routeC: 'route-c-url/:some-id/data', } const routeMapService: ProxedRouteMap<RouteMap> = new Proxy(routesMap, { // 此处写你的Proxy代理逻辑 }) as ProxedRouteMap<RouteMap>; // 此时TS会自动推导所有生成的方法,输入时也会有完整提示 routeMapService.getRouteAUrl() // 类型:() => string routeMapService.goToRouteBUrl({ param: '123' }) // 类型:(params?: Record<string, string | number>) => void
进阶优化(可选)
如果需要更严格的参数校验,还可以通过工具类型自动提取路由字符串里的参数名,调用方法时写错参数名会直接报错:
// 提取路由字符串中所有参数的工具类型 type ExtractRouteParams<T extends string> = T extends `${infer _}:${infer Param}/${infer Rest}` ? Param | ExtractRouteParams<Rest> : T extends `${infer _}:${infer Param}` ? Param : never; // 优化后的ProxedRouteMap类型 type ProxedRouteMap<T extends Record<string, string>> = { [P in keyof T as `get${Capitalize<P & string>}Url`]: ExtractRouteParams<T[P]> extends never ? () => string : (params: Record<ExtractRouteParams<T[P]>, string | number>) => string; } & { [P in keyof T as `goTo${Capitalize<P & string>}Url`]: ExtractRouteParams<T[P]> extends never ? () => void : (params: Record<ExtractRouteParams<T[P]>, string | number>) => void; }
内容的提问来源于stack exchange,提问作者RQman
相关产品推荐
相关产品推荐

