From ec50a80237df2dd0626d71f3ce0c48b723d43ca8 Mon Sep 17 00:00:00 2001 From: Christopher Horobin Date: Thu, 12 Dec 2024 19:58:09 +0100 Subject: [PATCH] fix(react-router): allow union when assigning (#2994) --- packages/react-router/src/utils.ts | 18 +++++++----- .../react-router/tests/useSearch.test-d.tsx | 29 +++++++++++++++++++ 2 files changed, 40 insertions(+), 7 deletions(-) diff --git a/packages/react-router/src/utils.ts b/packages/react-router/src/utils.ts index b9712bd6f8..11d8e56535 100644 --- a/packages/react-router/src/utils.ts +++ b/packages/react-router/src/utils.ts @@ -54,13 +54,17 @@ export type IsUnion = ( ? false : true -export type Assign = keyof TLeft extends never - ? TRight - : keyof TRight extends never - ? TLeft - : keyof TLeft & keyof TRight extends never - ? TLeft & TRight - : Omit & TRight +export type Assign = TLeft extends any + ? TRight extends any + ? keyof TLeft extends never + ? TRight + : keyof TRight extends never + ? TLeft + : keyof TLeft & keyof TRight extends never + ? TLeft & TRight + : Omit & TRight + : never + : never export type Timeout = ReturnType diff --git a/packages/react-router/tests/useSearch.test-d.tsx b/packages/react-router/tests/useSearch.test-d.tsx index 5a8ac93375..7908b9aac6 100644 --- a/packages/react-router/tests/useSearch.test-d.tsx +++ b/packages/react-router/tests/useSearch.test-d.tsx @@ -579,3 +579,32 @@ test('when a route has search params using SearchSchemaInput', () => { page: number }> }) + +test('when route has a union of search params', () => { + const rootRoute = createRootRoute() + + const postRoute = createRoute({ + getParentRoute: () => rootRoute, + path: '/', + validateSearch: (): { status: 'in' } | { status: 'out' } => { + return { status: 'in' } + }, + }) + + const indexRoute = createRoute({ + getParentRoute: () => postRoute, + path: '/', + validateSearch: (): { detail: string } => { + return { detail: 'detail' } + }, + }) + + const routeTree = rootRoute.addChildren([ + indexRoute.addChildren([indexRoute]), + ]) + // eslint-disable-next-line unused-imports/no-unused-vars + const router = createRouter({ routeTree }) + expectTypeOf(useSearch).returns.toEqualTypeOf< + { status: 'in'; detail: string } | { status: 'out'; detail: string } + > +})