Capítulo 24 de 57

Chapter 24: Link Options

Core Idea

The linkOptions() helper type-checks an object literal intended for Link/navigate/redirect eagerly (at definition time, not at usage time) and returns it unchanged, making navigation option objects safely reusable across multiple call sites.

Key Concepts

  • The Problem with Plain Object Literals: An untyped object like { to: '/dashboard', search: { search: '' } } has to inferred as string, which loosely matches any route, and type errors in it only surface once spread into <Link>, not at the point of definition.
  • linkOptions(options): A function that type-checks its object-literal argument against the same types Link uses, and returns the input as-is (fully inferred), so the object is safe and portable wherever ToOptions-shaped input is expected (Link props, navigate(), redirect()).
  • Reusability: A linkOptions() result can be spread into <Link {...opts} />, passed to navigate(opts), or thrown via redirect(opts) (e.g. inside a route's beforeLoad), all sharing one type-checked source of truth.
  • Array form: linkOptions([{ to, label, ... }, ...]) type-checks an array of option objects (e.g. for building a nav bar), while still allowing extra non-Link properties (like a custom label) to be inferred and used at the call site.

Code Examples

const dashboardLinkOptions = linkOptions({
  to: '/dashboard',
  search: { search: '' },
})

export const Route = createFileRoute('/dashboard')({
  component: DashboardComponent,
  validateSearch: (input) => ({ search: input.search }),
  beforeLoad: () => {
    // can be used in redirect
    throw redirect(dashboardLinkOptions)
  },
})

function DashboardComponent() {
  const navigate = useNavigate()
  return (
    <div>
      <button onClick={() => navigate(dashboardLinkOptions)} />
      <Link {...dashboardLinkOptions} />
    </div>
  )
}
  • What it demonstrates: One linkOptions() object reused across redirect, navigate, and Link.

Key Takeaways

  1. Always wrap shared/reused navigation option objects in linkOptions() instead of plain object literals, it catches type errors at definition time rather than at every usage site.
  2. linkOptions() accepts an array too, which is the idiomatic way to type-check a data-driven navigation menu while keeping extra display-only fields (like label) available.
  3. The same linkOptions() output is valid input for Link, useNavigate()'s returned function, and redirect(), since they all share the ToOptions/NavigateOptions type family.

Connects To

  • Ch 23: Navigation, defines the ToOptions/NavigateOptions/LinkOptions interfaces that linkOptions() type-checks against.
  • Ch 25: Custom Link, another way to wrap/reuse link-related logic in a component.