From bde4f8aeca80ba77882d9fd2c2e090a5699f14d9 Mon Sep 17 00:00:00 2001 From: chorobin Date: Wed, 7 May 2025 01:09:08 +0200 Subject: [PATCH 1/2] perf: improve perf a bit for Route.Link --- packages/react-router/src/link.tsx | 15 +++++++++++++++ packages/react-router/src/route.tsx | 17 ++++++++--------- packages/solid-router/src/link.tsx | 15 +++++++++++++++ packages/solid-router/src/route.tsx | 12 ++++++------ 4 files changed, 44 insertions(+), 15 deletions(-) diff --git a/packages/react-router/src/link.tsx b/packages/react-router/src/link.tsx index 56fba11d386..d0bbbdd8199 100644 --- a/packages/react-router/src/link.tsx +++ b/packages/react-router/src/link.tsx @@ -465,6 +465,21 @@ export type LinkComponent< props: LinkComponentProps, ) => React.ReactElement +export type LinkComponentRoute = < + TRouter extends AnyRouter = RegisteredRouter, + const TTo extends string | undefined = undefined, + const TMaskTo extends string = '', +>( + props: LinkComponentProps< + 'a', + TRouter, + TDefaultFrom, + TTo, + TDefaultFrom, + TMaskTo + >, +) => React.ReactElement + export function createLink( Comp: Constrain ReactNode>, ): LinkComponent { diff --git a/packages/react-router/src/route.tsx b/packages/react-router/src/route.tsx index 105341feb22..928116dba03 100644 --- a/packages/react-router/src/route.tsx +++ b/packages/react-router/src/route.tsx @@ -42,7 +42,7 @@ import type { UseLoaderDepsRoute } from './useLoaderDeps' import type { UseParamsRoute } from './useParams' import type { UseSearchRoute } from './useSearch' import type { UseRouteContextRoute } from './useRouteContext' -import type { LinkComponent } from './link' +import type { LinkComponentRoute } from './link' declare module '@tanstack/router-core' { export interface UpdatableRouteOptionsExtensions { @@ -63,7 +63,7 @@ declare module '@tanstack/router-core' { useLoaderDeps: UseLoaderDepsRoute useLoaderData: UseLoaderDataRoute useNavigate: () => UseNavigateResult - Link: LinkComponent<'a', TFullPath> + Link: LinkComponentRoute } } @@ -137,13 +137,12 @@ export class RouteApi< return notFound({ routeId: this.id as string, ...opts }) } - Link: LinkComponent<'a', RouteTypesById['fullPath']> = + Link: LinkComponentRoute['fullPath']> = React.forwardRef((props, ref: React.ForwardedRef) => { const router = useRouter() const fullPath = router.routesById[this.id as string].fullPath return - }) as unknown as LinkComponent< - 'a', + }) as unknown as LinkComponentRoute< RouteTypesById['fullPath'] > } @@ -255,11 +254,11 @@ export class Route< return useNavigate({ from: this.fullPath }) } - Link: LinkComponent<'a', TFullPath> = React.forwardRef( + Link: LinkComponentRoute = React.forwardRef( (props, ref: React.ForwardedRef) => { return }, - ) as unknown as LinkComponent<'a', TFullPath> + ) as unknown as LinkComponentRoute } export function createRoute< @@ -446,11 +445,11 @@ export class RootRoute< return useNavigate({ from: this.fullPath }) } - Link: LinkComponent<'a', '/'> = React.forwardRef( + Link: LinkComponentRoute<'/'> = React.forwardRef( (props, ref: React.ForwardedRef) => { return }, - ) as unknown as LinkComponent<'a', '/'> + ) as unknown as LinkComponentRoute<'/'> } export function createRootRoute< diff --git a/packages/solid-router/src/link.tsx b/packages/solid-router/src/link.tsx index bc9e3f23030..c4f406d915a 100644 --- a/packages/solid-router/src/link.tsx +++ b/packages/solid-router/src/link.tsx @@ -522,6 +522,21 @@ export type LinkComponent< props: LinkComponentProps, ) => Solid.JSX.Element +export type LinkComponentRoute = < + TRouter extends AnyRouter = RegisteredRouter, + const TTo extends string | undefined = undefined, + const TMaskTo extends string = '', +>( + props: LinkComponentProps< + 'a', + TRouter, + TDefaultFrom, + TTo, + TDefaultFrom, + TMaskTo + >, +) => Solid.JSX.Element + export function createLink( Comp: Constrain Solid.JSX.Element>, ): LinkComponent { diff --git a/packages/solid-router/src/route.tsx b/packages/solid-router/src/route.tsx index 2d89232acc2..c14f0615872 100644 --- a/packages/solid-router/src/route.tsx +++ b/packages/solid-router/src/route.tsx @@ -42,7 +42,7 @@ import type { UseParamsRoute } from './useParams' import type { UseSearchRoute } from './useSearch' import type * as Solid from 'solid-js' import type { UseRouteContextRoute } from './useRouteContext' -import type { LinkComponent } from './link' +import type { LinkComponentRoute } from './link' declare module '@tanstack/router-core' { export interface UpdatableRouteOptionsExtensions { @@ -63,7 +63,7 @@ declare module '@tanstack/router-core' { useLoaderDeps: UseLoaderDepsRoute useLoaderData: UseLoaderDataRoute useNavigate: () => UseNavigateResult - Link: LinkComponent<'a', TFullPath> + Link: LinkComponentRoute } } @@ -132,7 +132,7 @@ export class RouteApi< return notFound({ routeId: this.id as string, ...opts }) } - Link: LinkComponent<'a', RouteTypesById['fullPath']> = ( + Link: LinkComponentRoute['fullPath']> = ( props, ) => { const router = useRouter() @@ -242,7 +242,7 @@ export class Route< return useNavigate({ from: this.fullPath }) } - Link: LinkComponent<'a', TFullPath> = (props) => { + Link: LinkComponentRoute = (props) => { return } } @@ -427,8 +427,8 @@ export class RootRoute< return useNavigate({ from: this.fullPath }) } - Link: LinkComponent<'a', '/'> = (props) => { - return + Link: LinkComponentRoute<'/'> = (props) => { + return } } From fee7b5229d00a5470240f060a410cea39af46156 Mon Sep 17 00:00:00 2001 From: chorobin Date: Wed, 7 May 2025 01:25:13 +0200 Subject: [PATCH 2/2] chore: fix tests --- packages/react-router/tests/routeApi.test-d.tsx | 5 +++-- packages/solid-router/tests/routeApi.test-d.tsx | 4 ++-- 2 files changed, 5 insertions(+), 4 deletions(-) diff --git a/packages/react-router/tests/routeApi.test-d.tsx b/packages/react-router/tests/routeApi.test-d.tsx index de7ff81ca36..a51a50b10ff 100644 --- a/packages/react-router/tests/routeApi.test-d.tsx +++ b/packages/react-router/tests/routeApi.test-d.tsx @@ -1,6 +1,7 @@ import { describe, expectTypeOf, test } from 'vitest' import { createRootRoute, createRoute, createRouter, getRouteApi } from '../src' -import type { LinkComponent, MakeRouteMatch, UseNavigateResult } from '../src' +import type { MakeRouteMatch, UseNavigateResult } from '../src' +import type { LinkComponentRoute } from '../src/link' const rootRoute = createRootRoute() @@ -90,7 +91,7 @@ describe('getRouteApi', () => { test('Link', () => { const Link = invoiceRouteApi.Link expectTypeOf(Link).toEqualTypeOf< - LinkComponent<'a', '/invoices/$invoiceId'> + LinkComponentRoute<'/invoices/$invoiceId'> >() }) }) diff --git a/packages/solid-router/tests/routeApi.test-d.tsx b/packages/solid-router/tests/routeApi.test-d.tsx index 805eec55658..a06c99708f7 100644 --- a/packages/solid-router/tests/routeApi.test-d.tsx +++ b/packages/solid-router/tests/routeApi.test-d.tsx @@ -1,8 +1,8 @@ import { describe, expectTypeOf, test } from 'vitest' import { createRootRoute, createRoute, createRouter, getRouteApi } from '../src' -import type { LinkComponent } from '../src' import type { Accessor } from 'solid-js' import type { MakeRouteMatch, UseNavigateResult } from '@tanstack/router-core' +import type { LinkComponentRoute } from '../src/link' const rootRoute = createRootRoute() @@ -100,7 +100,7 @@ describe('getRouteApi', () => { test('Link', () => { const Link = invoiceRouteApi.Link expectTypeOf(Link).toEqualTypeOf< - LinkComponent<'a', '/invoices/$invoiceId'> + LinkComponentRoute<'/invoices/$invoiceId'> >() }) })