TypeScript中如何根据路由name推断对应path的返回类型?
解决TypeScript路由跳转函数的精确类型推断问题
先看定义的类型与常量:
interface Route { name: string, path: string } const routes = [ { name: "first", path: "/first" }, { name: "second", path: "/second" } ] as const
需求是创建一个to函数,传入routes和路由name时,返回对应路由的精确path类型(比如传"first"返回"/first"类型,传"second"返回"/second"类型)。但当前泛型写法返回的是联合类型,不符合预期:
const to = <Routes extends ReadonlyArray<Route>, CurrentRoute extends Routes[number]>(routes: Routes, name: CurrentRoute["name"]): CurrentRoute["path"] => { // 实现逻辑无关紧要 return "" as CurrentRoute["path"] } const path = to(routes, "first") // 不符合预期:返回联合类型而非单一字符串类型
解决方案
通过构建路由名称与路径的映射类型,让TypeScript能根据传入的name精确推断返回的path类型:
// 把路由数组转换为 { [name]: path } 的映射类型 type RouteMap<T extends ReadonlyArray<{ name: string; path: string }>> = { [K in T[number]["name"]]: Extract<T[number], { name: K }>["path"] } const to = <T extends ReadonlyArray<{ name: string; path: string }>>( routes: T, name: keyof RouteMap<T> ): RouteMap<T>[typeof name] => { // 实现逻辑可忽略,这里仅做类型断言满足语法要求 return routes.find(r => r.name === name)?.path as RouteMap<T>[typeof name] } // 测试效果 const path1 = to(routes, "first") // 类型推断为 "/first" const path2 = to(routes, "second") // 类型推断为 "/second" const path3 = to(routes, "third") // 传入不存在的name会触发类型错误
原理说明
RouteMap类型通过索引签名遍历路由数组的每个元素,将路由的name作为键,对应的path作为值,构建出精准的名称-路径映射。to函数的泛型T绑定传入的routes类型,name参数被约束为映射类型的键,返回值则是该键对应的路径类型,从而实现精确的类型推断。
内容的提问来源于stack exchange,提问作者Amin NAIRI
相关产品推荐
相关产品推荐

