ARTICLE DETAIL

资讯详情

深耕郑州网站建设与运营推广的一线实战洞察。

TanStack Router 的 isRedirect 函数:识别与收窄 Redirect 对象的类型守卫

TanStack Router 的 isRedirect 函数:识别与收窄 Redirect 对象的类型守卫 TanStack Router 的 isRedirect 函数识别与收窄 Redirect 对象的类型守卫【免费下载链接】router A client-first, server-capable, fully type-safe router and full-stack framework for the web (React and more).项目地址: https://gitcode.com/GitHub_Trending/ro/routerisRedirect是 TanStack Router本仓库router-core包提供的运行时类型守卫用于判断一个值是否是框架生成的 redirect 对象。它最常在 loader/beforeLoad 返回值、throw redirect(...)被 catch 到的异常、或中间件结果等“值类型未知unknown”的边界处使用帮助你在不确定对象来源时安全地做重定向分支处理。读完本文你可以掌握isRedirect的签名与参数、其底层判定原理Response实例 options标记以及它在客户端加载管线、服务端渲染和 Start 框架中间件中的真实调用位置。什么是 isRedirectisRedirect函数用于确定一个对象是否为 redirect 对象。在 TanStack Router 中redirect()工厂函数详见 RedirectType 文档 与 redirect.ts生成的 redirect 对象本质上是一个被扩展了导航选项的Response实例。当你拿到一个来源不确定的值——比如从 loader 透传出来的unknown、被try/catch捕获的异常对象、或从序列化数据还原回来的对象——就需要isRedirect来做可靠的运行时判别而不是依赖instanceof某个自定义类。它是与isNotFound并列的控制流判别工具两者共同覆盖路由数据加载管线中“不是普通返回值而是导航指令”的两种特殊结果。isRedirect 的签名与参数根据 API 文档isRedirectFunction.mdisRedirect接受单个参数input参数类型必填说明inputunknown是待检查是否为 redirect 对象的对象返回值类型boolean对象是 redirect 对象时返回true否则返回false文档示例import { isRedirect } from tanstack/react-router function somewhere(obj: unknown) { if (isRedirect(obj)) { // 此处 obj 被收窄为 redirect 对象 // ... } }值得注意的是isRedirect不仅返回布尔值在 TypeScript 层面它是一个类型守卫type predicate。从 redirect.ts 源码看实际签名如下/** Check whether a value is a TanStack Router redirect Response. */ export function isRedirect(obj: any): obj is AnyRedirect { return obj instanceof Response !!(obj as any).options }这意味着在if (isRedirect(obj))分支内obj的类型会从unknown/any被自动收窄为AnyRedirect你可以直接访问它的options、status、headers等成员而不需要额外断言。AnyRedirect即Redirectany, any, any, any, any是所有路由/来源泛型实例化的联合形态定义于 redirect.ts。底层原理为什么是instanceof Response options理解isRedirect的关键是理解redirect()工厂如何构造对象。阅读 redirect.tsexport function redirect...(opts: RedirectOptions...): Redirect... { // 1. 状态码默认 307也可用已废弃的 code 字段 opts.statusCode opts.statusCode || opts.code || 307 const headers new Headers(opts.headers) // 2. 外部 href 自动写入 Location 头 if (opts.href headers.get(Location) null) { headers.set(Location, opts.href) } // 3. 构造一个标准 Response const response new Response(null, { status: opts.statusCode, headers, }) // 4. 把导航选项挂到 Response 实例上作为是路由重定向的标记 ;(response as Redirect...).options opts // 5. 支持 throw 语义throw redirect({ throw: true }) if (opts.throw) { throw response } return response as Redirect... }由此得到三条判定链上的事实redirect 对象首先是Response实例。它携带 HTTP 语义status、headers这使得 redirect 天然可以在服务端作为标准响应返回也能在客户端导航中被路由消费。.options是路由专属的标记字段。普通new Response()或 fetch 拿到的响应不会有options属性因此isRedirect可以把它和一切看起来像 Response 但不是重定向的值区分开。Redirect类型本身见 redirect.ts定义为Response { options: NavigateOptions... }——即一个带有导航选项的 Response与isRedirect的运行时检查一一对应。options中保留了redirect()调用时的完整入参to/href、params、search、replace、statusCode、headers等标准导航选项以及throw语义。这就是为什么框架内部在处理重定向时能直接从对象上还原出目标路由。另外两个同文件导出的相关工具可以顺带了解redirect.tsisResolvedRedirect(obj)在isRedirect基础上进一步判断obj.options.href是否存在即该重定向是否指向外部 URLparseRedirect(obj)从序列化后的普通对象带isSerializedRedirect标记还原出 redirect 对象用于跨进程传递重定向的场域。框架内部的真实调用位置isRedirect不只是给开发者用的工具它也是路由核心管线识别重定向的控制点。以下调用链均可在仓库源码中逐一验证客户端加载管线loader/beforeLoad 结果归一化在 load-client.ts 的normalize函数中每个路由加载器的返回值/抛出的值都会被分类function normalize(value: unknown, rejected: boolean, routeId?: string): RawLoaderOutcome { if (isRedirect(value)) { return [REDIRECTED, value] } if (isNotFound(value)) { value.routeId || routeId return [NOT_FOUND, value] } if (!rejected) { return [SUCCESS, value] } // ... return [ERROR, value] }可以看到无论重定向对象是被返回的return redirect(...)还是被抛出的throw redirect({ throw: true })此时走rejected: true分支只要通过isRedirect识别都会被归一化为REDIRECTED结果再交给后续的materializeRedirect流程驱动导航。这正是redirect({ throw: true })能与return redirect(...)等价工作的底层原因。严格参数解析中的重定向放行在 router.ts 中路由参数的严格解析extractStrictParams通常由 search/params 校验器触发会捕获错误并专门放行isNotFound与isRedirecttry { extractStrictParams(route, strictParams) } catch (err: any) { if (isNotFound(err) || isRedirect(err)) { paramsError err } else { paramsError new PathParamError(err.message, { cause: err }) } // ... }也就是说如果你的 search 校验器在参数不合法时throw redirect(...)例如该用户应跳转到其专属页路由器会识别这是一个重定向并正常处理而不是把它包装成PathParamError走错误界面。isRedirect在这里起到了控制流异常穿透的作用。服务端渲染管线服务端的 loader 归一化逻辑与客户端对称位于 load-server.tsfunction normalize(value: unknown, rejected: boolean): LoaderOutcome { if (isRedirect(value)) { return [REDIRECTED, value] } if (isNotFound(value)) { return [NOT_FOUND, value] } // ... }SSR 过程中 loader 抛出的重定向同样经由isRedirect被识别最终以{ type: redirect; redirect: AnyRedirect }的结果形态参与响应决策。Start 框架中间件识别特殊响应在tanstack/react-start等服务端框架的处理器中createStartHandler.ts 定义了function isSpecialResponse(value: unknown): value is Response { return value instanceof Response || isRedirect(value) }从源码结构看isRedirect被用于判断中间件/处理函数返回的未知值是否是一个需要按 HTTP 响应特殊处置的对象例如延迟响应、不可被 defer 的分支。换言之中间件直接return redirect(...)的写法能够生效也依赖这一识别逻辑。典型实战用法1. 处理来源未知的返回值或异常当你编写一个复用函数接收 loader 结果或需要在catch块中区分业务错误与重定向时import { isRedirect, isNotFound } from tanstack/react-router async function handleLoaderResult(result: unknown) { if (isRedirect(result)) { // result 已收窄为 AnyRedirect可读取 status/headers/options console.log(redirect to, result.options.href ?? result.options.to, result.status) return } if (isNotFound(result)) { // 404 分支 return } // 普通数据 }2. 在 beforeLoad 中透传上游抛出的重定向beforeLoad里若调用其他可能抛重定向的逻辑需要让重定向继续向上抛而不是被吞掉const settingsRoute createRoute({ id: settings, beforeLoad: async ({ context }) { try { await requireAuth(context) // 内部可能 throw redirect({ href: /login }) } catch (err) { if (isRedirect(err)) { throw err // 透传重定向交由路由器处理 } throw err } }, // ... })由于框架在normalize阶段对rejected的值同样执行isRedirect检查见上文 load-client.ts透传即可无需自行转换为返回值。3. 与 isResolvedRedirect 区分内外部重定向import { isResolvedRedirect, redirect } from tanstack/react-router if (isResolvedRedirect(value)) { // value.options.href 必然存在是外部 URL 重定向 // 例如redirect({ href: https://auth.example.com }) }外部href重定向在redirect()创建时已自动写入Location请求头见 redirect.ts服务端可直接将该Response作为 HTTP 响应返回。使用注意事项与边界判定条件是双重的obj instanceof Response obj.options。一个手写的普通new Response()不会命中一个普通对象例如序列化后的{ href, statusCode }也不会命中。跨序列化边界的重定向应先经parseRedirect还原再判断。Redirect类型即Response { options: NavigateOptions }redirect.ts。API 文档 RedirectType.md 描述的是redirect()的入参形态statusCode/throw/headers 导航属性实际运行时的对象结构以源码为准。默认状态码为 307redirect()在未显式提供statusCode时回退到 307redirect.tscode字段已被标记为废弃新代码应使用statusCode。isRedirect在各框架包中均有再导出tanstack/react-router、tanstack/solid-router、tanstack/vue-router的入口如 react-router/src/index.tsx都从tanstack/router-core转出了该函数见 router-core/src/index.ts因此无论使用哪个框架绑定导入方式一致。小结isRedirect以两行源码instanceof Responseoptions标记承担了 TanStack Router 中重定向识别的全部职责它是 TypeScript 的类型收窄守卫是客户端/服务端 loader 归一化的分派依据是严格参数解析中控制流异常的放行通道也是 Start 框架中间件识别特殊响应的组件。掌握它之后你可以在任何unknown边界处可靠地检测、收窄并透传重定向对象。【免费下载链接】router A client-first, server-capable, fully type-safe router and full-stack framework for the web (React and more).项目地址: https://gitcode.com/GitHub_Trending/ro/router创作声明:本文部分内容由AI辅助生成(AIGC),仅供参考
返回列表