2026/9/14 2:54:29

TanStack Router ToOptions 类型详解:类型安全的导航目标描述与路由遮罩

TanStack Router ToOptions 类型详解:类型安全的导航目标描述与路由遮罩 TanStack Router ToOptions 类型详解类型安全的导航目标描述与路由遮罩【免费下载链接】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本篇指南聚焦 TanStack Router本仓库packages/*实现的客户端优先、全栈类型安全路由框架中的ToOptions类型。ToOptions是描述一次导航要去哪里、带什么参数、以什么方式呈现的核心契约useNavigate、Link、matchRoute以及redirect等 API 的参数类型都构建在它之上。读完本篇你将掌握ToOptions各属性from/to/hash/state/search/params/mask的取值形态与类型收窄机制并能基于源码理解其maskedLocation的构建逻辑。ToOptions 是什么官方 API 文档 ToOptionsType.md 对该类型的定义是ToOptions包含若干用于描述一个路由目标的属性其中包括用于路由遮罩route masking的mask。文档给出的类型形态如下type ToOptions { from?: ValidRoutePath | string to?: ValidRoutePath | string hash?: true | string | ((prev?: string) string) state?: true | HistoryState | ((prev: HistoryState) HistoryState) } SearchParamOptions PathParamOptions MaskOptions type SearchParamOptions { search?: true | TToSearch | ((prev: TFromSearch) TToSearch) } type PathParamOptions { params?: | true | Recordstring, TPathParam | ((prev: TFromParams) TToParams) } type MaskOptions { mask?: ToMaskOptionsTRouter, TMaskFrom, TMaskTo }在仓库源码中该类型定义于 link.ts并携带 5 个泛型参数这正是其全量类型安全的来源// packages/router-core/src/link.ts#L360-L366 export type ToOptions TRouter extends AnyRouter RegisteredRouter, TFrom extends string string, TTo extends string | undefined ., TMaskFrom extends string TFrom, TMaskTo extends string ., ToSubOptionsTRouter, TFrom, TTo MaskOptionsTRouter, TMaskFrom, TMaskToTRouter具体路由实例类型决定路由树、各路由的allParams与fullSearchSchemaTFrom导航出发路由路径字面量TTo目标路径字面量.表示当前路由TMaskFrom/TMaskTo遮罩路由的出发/目标路径独立参与类型收窄。文档中的ValidRoutePath、TToSearch等是简化的泛型占位符源码中分别由ToPathOption/FromPathOption等约束类型展开下文逐属性展开。属性总览属性类型说明fromRoutePathsTRouter[routeTree]出发路由useNavigate场景下通常由getRouteApi自动提供此处主要用于链接/跨路由导航toToPathOptionTRouter, TFrom, TTo目标路由路径支持绝对路径与相对路径如../profile并带编辑器路径补全hashtrue \| Updaterstring锚点true表示保留当前 hashstatetrue \| NonNullableUpdaterParsedHistoryState, HistoryStatehistory statetrue表示保留当前 statesearchtrue/ 对象 /(prev) 对象目标搜索参数按目标路由的validateSearch校验paramstrue/Recordstring, TPathParam/(prev) 对象路径参数按目标路由的allParams校验maskToMaskOptionsTRouter, TMaskFrom, TMaskTo路由遮罩实际路由与展示路径分离unsafeRelativepath源码级逃生舱仅 link.ts 中定义文档未列出from 与 to路径约束与自动补全to与from的类型并非简单的string。源码 link.ts#L616-L632 给出export type ToPathOption TRouter extends AnyRouter AnyRouter, TFrom extends string string, TTo extends string | undefined string, ConstrainLiteral TTo, RelativeToPathAutoComplete TRouter, NoInferTFrom extends string ? NoInferTFrom : , NoInferTTo string export type FromPathOptionTRouter extends AnyRouter, TFrom ConstrainLiteral TFrom, RoutePathsTRouter[routeTree] 从源码结构看ToPathOption会在三种候选集之间做联合绝对路径RouteToPath即整棵路由树的路径、相对当前路由可达的路径RelativeToCurrentPath、相对父级可达的路径RelativeToParentPath处理../x形式。ConstrainLiteral的作用是把泛型TTo约束回这些候选字面量上——写错路径会在编译期直接报错编辑器中还能获得路径补全。to是必选还是可选由MakeToRequired决定link.ts#L421-L431当TFrom无法推断退化为string时放宽为可选避免在未绑定具体路由上下文的场景误报能确定TFrom且TTo是具体字面量时则要求必填。hash 与 state三种取值形态hash和state采用统一的三态设计源码定义见 link.ts#L433-L442export type ToSubOptionsProps TRouter extends AnyRouter RegisteredRouter, TFrom extends RoutePathsTRouter[routeTree] | string string, TTo extends string | undefined ., MakeToRequiredTRouter, TFrom, TTo { hash?: true | Updaterstring state?: true | NonNullableUpdaterParsedHistoryState, HistoryState from?: FromPathOptionTRouter, TFrom {} unsafeRelative?: path }其中Updater/NonNullableUpdater定义在 utils.ts#L87-L91本质是TResult | ((prev: TPrevious) TResult)联合。因此hash: true导航后保留地址栏现有锚点hash: #section直接覆盖hash: (prev) next基于旧锚点函数式更新state: true保留当前 history state传对象则整体替换传函数时入参prev的类型是ParsedHistoryState比HistoryState多携带路由内部元数据返回值是普通HistoryState。这与文档中(prev: HistoryState) HistoryState的简化写法语义一致但源码的prev更精确。配合NavigateOptionProps见replace、resetScroll、viewTransition等link.ts#L301-L358ToOptions构成完整的导航描述。search 与 params按需必填的类型收窄search和params的可选性不是固定的而是由目标路由是否要求这些参数动态推导的。源码链路如下link.ts#L541-L614export interface MakeOptionalSearchParams... { search?: true | (ParamsReducerTRouter, SEARCH, TFrom, TTo {}) } export interface MakeRequiredSearchParams... { search: MakeRequiredParamsReducerTRouter, SEARCH, TFrom, TTo {} } export type SearchParamOptionsTRouter, TFrom, TTo IsRequiredTRouter, SEARCH, TFrom, TTo extends never ? MakeOptionalSearchParamsTRouter, TFrom, TTo : MakeRequiredSearchParamsTRouter, TFrom, TToIsRequiredlink.ts#L590-L604会把TFrom、TTo经ResolveRelativePath解析成真实路径再取目标路由的allParams/fullSearchSchemaInput做必填性判断。由此得到两种编译期行为目标路由有必填 search/paramssearch/params变成必填属性缺省会直接报错MakeRequiredParamsReducer还允许传true继承当前值前提是当前参数已满足目标要求目标路由参数全部可选两者退化为可选。参数值本身支持三种形态ParamsReducer定义见 link.ts#L444-L460true保留出发路由上同名参数的当前值字面量对象全量替换params: { id: 42 }更新函数search: (prev) ({ ...prev, tab: settings })函数入参是出发路由的完整参数/搜索类型返回值按目标路由的输入 schema 校验。一个可复制的典型用法与上述类型完全吻合// 从 /user 导航到 /user/$id保留当前 search仅更新其中 tab router.navigate({ to: /user/$id, params: { id: 42 }, search: (prev) ({ ...prev, tab: settings }), })MaskOptions路由遮罩route maskingmask是ToOptions中最有特色的部分。遮罩的含义是实际渲染某条路由但地址栏展示另一条路径——典型场景是把详情页以模态框形式呈现分享链接时再解除遮罩回到真实 URL。源码中MaskOptions与ToMaskOptions定义在 link.ts#L368-L383export interface MaskOptions in out TRouter extends AnyRouter, in out TMaskFrom extends string, in out TMaskTo extends string, { _fromLocation?: ParsedLocation mask?: ToMaskOptionsTRouter, TMaskFrom, TMaskTo } export type ToMaskOptions TRouter extends AnyRouter RegisteredRouter, TMaskFrom extends string string, TMaskTo extends string ., ToSubOptionsTRouter, TMaskFrom, TMaskTo { unmaskOnReload?: boolean }注意ToMaskOptions本身递归复用ToSubOptions——也就是说mask内部可以带自己的to/params/search且这些参数按遮罩路由TMaskTo的类型收窄而非真实目标路由这是TMaskFrom/TMaskTo两个独立泛型的意义。unmaskOnReload控制页面刷新后是否解除遮罩。源码如何消费 maskRouterCore构建 location 时router.ts#L2146-L2175const next build(opts) if (opts.mask) { next.maskedLocation build({ from: opts.from, ...opts.mask, }) } else if (this.options.routeMasks) { const match findFlatMatchRouteMaskTRouteTree( next.pathname, this.processedTree, ) if (match) { const params Object.assign(Object.create(null), match.rawParams) const { from: _from, params: maskParams, ...maskProps } match.route const nextParams resolveNextParams(maskParams, params) next.maskedLocation build({ from: opts.from, ...maskProps, params: nextParams, }) } }从源码结构看遮罩解析有两条路径显式opts.mask以同一套build逻辑基于mask.to额外构建一个maskedLocation与真实 location 并存路由树级routeMasks未显式传mask时若构建后的真实路径命中了路由树中的某个RouteMask由createRouteMask声明则自动套用该 mask 的to/ 默认params。params也支持函数形式会以真实路由匹配到的参数为上下文求值。提交到 history 时unmaskOnReload的取值优先级为导航级选项 遮罩自身选项 路由级全局unmaskOnReload见 router.ts#L2249-L2253 的??链。后续读取 location 时对外暴露的一律是location.maskedLocation ?? locationrouter.ts#L2354、#L2530保证useLocation等 hook 拿到的始终是用户可见的地址。完整的路由遮罩概念、模态框案例与刷新解除行为可继续阅读 route-masking 指南 与 RouteMaskType.md、ToMaskOptionsType.md仓库内 examples/react/location-masking 提供了一个可运行的遮罩示例应用。ToOptions 在上层 API 中的复用ToOptions是整个导航体系的公共底座NavigateOptions直接在其上叠加行为开关link.ts#L289-L295export type NavigateOptions TRouter extends AnyRouter RegisteredRouter, TFrom extends string string, TTo extends string | undefined ., TMaskFrom extends string TFrom, TMaskTo extends string ., ToOptionsTRouter, TFrom, TTo, TMaskFrom, TMaskTo NavigateOptionProps由此形成的复用关系均以源码为据useNavigate返回的navigate接受NavigateOptionsuseNavigate.tsLink的to相关 props 是NavigateOptions LinkOptionsPropslink.ts#L702-L704因此Link to mask search params与编程式导航享受同一套类型收窄redirect()/createRedirect()同样以NavigateOptions为参数redirect.ts#L13-L16loader 内跳转时可用完全一致的写法matchRoute的路由位置参数直接就是ToOptionsrouter.ts#L723-L744用于在组件外判断某位置是否命中某路由并取出参数preloadRoute亦以NavigateOptions为参数router.ts#L696-L721。行为类开关replace、resetScroll、viewTransition、ignoreBlocker、reloadDocument、href、hashScrollIntoView不属于ToOptions本体而属于NavigateOptionPropsToOptions只负责去哪里、带什么、以什么面貌呈现。更多说明见 NavigateOptionsType.md 与 LinkOptionsType.md。小结ToOptions是 TanStack Router 中导航目标的类型契约from/to决定去向且带路径补全hash/state支持true、字面量、更新函数三态search/params按目标路由 schema 动态决定必填性与校验mask提供真实路由与展示路径分离的遮罩能力其可选性/必填性由IsRequiredMakeRequired/Optional*条件类型在编译期推导link.ts#L590-L614把运行时参数错误前移到类型检查阶段mask的最终落地是maskedLocation的并行构建router.ts#L2148-L2172并可通过routeMasks在路由树上声明式复用需要继续深入时建议按 ToOptionsType.md → NavigateOptionsType.md → route-masking 指南 → examples/react/location-masking 的顺序阅读。【免费下载链接】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),仅供参考