Capítulo 48 de 57

Chapter 48: Type Utilities

Core Idea

TanStack Router exposes a small set of stable, externally-focused type utilities (ValidateLinkOptions, ValidateLinkOptionsArray, ValidateRedirectOptions, ValidateNavigateOptions, ValidateFromPath) for type-checking navigation-related props in custom wrapper components, avoiding the performance and ergonomics problems of using internal types like LinkProps directly.

Key Concepts

  • ValidateLinkOptions<TRouter, TOptions>: Type-checks an object literal against Link options at the inference site, used for generic components (e.g. a HeadingLink) that forward linkOptions to <Link>.
  • ValidateLinkOptionsArray<TRouter, TItems, TFrom?>: Array variant for components rendering lists of links (e.g. a Menu), optionally fixed to a common from path.
  • ValidateFromPath<TRouter, TFrom>: Type-checks a from path string used to narrow an array of link options to navigate relative to that path.
  • ValidateRedirectOptions<TRouter, TOptions>: Type-checks object literals against redirect() options, for functions that conditionally throw a redirect (e.g. a fetchOrRedirect helper).
  • ValidateNavigateOptions<TRouter, TOptions>: Type-checks object literals against navigate() options, for custom hooks wrapping useNavigate.
  • Two-overload pattern: Public generic components declare a strict overload (with TRouter/TOptions type params) plus a permissive implementation overload, avoiding type assertions inside the component body.
  • TRouter always specified, TOptions at inference sites: Best-practice guidance, TRouter should be the RegisteredRouter default on public signatures; TOptions should be left to be inferred where the consuming code calls the component.

Code Examples

export interface HeaderLinkProps<
  TRouter extends RegisteredRouter = RegisteredRouter,
  TOptions = unknown,
> {
  title: string
  linkOptions: ValidateLinkOptions<TRouter, TOptions>
}

export function HeadingLink<TRouter extends RegisteredRouter, TOptions>(
  props: HeaderLinkProps<TRouter, TOptions>,
): React.ReactNode
export function HeadingLink(props: HeaderLinkProps): React.ReactNode {
  return (
    <>
      <h1>{props.title}</h1>
      <Link {...props.linkOptions} />
    </>
  )
}
  • What it demonstrates: A generic, type-safe wrapper component around <Link> that fully validates its linkOptions prop against the registered router's route map.

Key Takeaways

  1. Use these Validate* utilities instead of the bare internal types (LinkProps, etc.) when building reusable navigation components, they're purpose-built for external consumption and inference.
  2. The double-overload pattern (typed public signature + loose implementation signature) is the idiomatic way to avoid type assertions while keeping full type safety for callers.
  3. ValidateLinkOptionsArray combined with ValidateFromPath lets you build type-safe menu/nav-list components scoped to a common relative from.

Connects To

  • Ch 47: Type Safety, explains why the bare LinkProps type is expensive for TS performance and why these utilities exist.
  • Ch 56: Router API Reference, lists LinkOptionsType, NavigateOptionsType, and related type references.