You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

如何封装Tanstack Router的Link组件并保留类型安全性

问题

我希望将TanStack Router的Link组件封装到自定义组件中,同时能向该组件传递Link所需的props。具体来说,我想制作一个可复用组件,用TanStack Router的Link包裹外部按钮组件,示例代码如下:

import { Link, LinkOptions } from '@tanstack/router'

interface ButtonLinkProps {
  // 如何实现类型安全?当前它的类型为`string | undefined`,而非我定义的有效路由
  to: LinkOptions['to']
  children: string
}

export function ButtonLink(props: ButtonLinkProps) {
  return (
    <Link to={props.to} params={{}} search={{}}>
      <Button component='span'>{props.children}</Button>
    </Link>
  )
}

直接使用Link组件时,to prop仅能传入已定义的路由,但我不清楚如何在自定义组件中定义to prop以实现相同的类型安全效果,例如使用<ButtonLink to='/'>Link</ButtonLink>时的类型检查。

解决方案

要实现和原生Link组件一致的类型安全,核心是利用TanStack Router代码生成工具生成的路由类型定义,以下是两种可行方案:

方案1:继承LinkProps类型(推荐)

TanStack Router会在路由生成文件(通常是router.ts)中导出LinkProps类型,该类型已经绑定了你所有已定义的路由信息,直接继承它就能自动获得类型安全的to、params、search等props:

import { Link, LinkProps } from '@tanstack/router';
import { Router } from './router'; // 导入生成的Router类型
import Button from './your-button-component'; // 导入你的外部按钮组件

// 继承LinkProps并扩展自定义属性,Omit去掉默认children后自定义类型(可选)
interface ButtonLinkProps extends Omit<LinkProps<Router>, 'children'> {
  children: string;
  // 可添加Button组件的自定义props,比如variant、size等
}

export function ButtonLink(props: ButtonLinkProps) {
  const { children, ...linkProps } = props;
  return (
    <Link {...linkProps}>
      <Button component='span'>{children}</Button>
    </Link>
  );
}

方案2:显式约束路由名称类型

如果你只需要部分Link的props,可以直接用生成的Router['routeNames']来约束to的取值范围,确保只能传入已定义的路由:

import { Link } from '@tanstack/router';
import { Router } from './router'; // 导入生成的Router类型
import Button from './your-button-component';

interface ButtonLinkProps {
  to: Router['routeNames']; // 仅允许传入已定义的路由名称
  children: string;
  // 按需添加其他Link的props,类型自动匹配对应路由的参数
  params?: Parameters<typeof Link>[0]['params'];
  search?: Parameters<typeof Link>[0]['search'];
}

export function ButtonLink(props: ButtonLinkProps) {
  const { children, ...linkProps } = props;
  return (
    <Link {...linkProps}>
      <Button component='span'>{children}</Button>
    </Link>
  );
}

关键说明

  • 必须确保你已经通过TanStack Router的代码生成工具(比如@tanstack/router-cli)生成了路由类型文件,否则无法获取Router和LinkProps类型
  • 两种方案都能实现:当传入未定义的路由时,TypeScript会直接抛出类型错误,和原生Link组件的类型检查效果完全一致

内容的提问来源于stack exchange,提问作者Sjiep

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.07.16 09:33:07