diff --git a/packages/react-router/src/link.tsx b/packages/react-router/src/link.tsx index 293fb79108a..09125f71386 100644 --- a/packages/react-router/src/link.tsx +++ b/packages/react-router/src/link.tsx @@ -172,11 +172,9 @@ export type SearchParamOptions< TFromSearchEnsured = '/' extends TFrom ? FullSearchSchema : Expand< - UnionToIntersection< PickRequired< RouteByPath['types']['fullSearchSchema'] > - > >, TFromSearchOptional = Omit< FullSearchSchema, diff --git a/packages/react-router/src/routeInfo.ts b/packages/react-router/src/routeInfo.ts index 7fc6719a723..575946a06d5 100644 --- a/packages/react-router/src/routeInfo.ts +++ b/packages/react-router/src/routeInfo.ts @@ -1,5 +1,5 @@ import { AnyRoute, Route } from './route' -import { Expand, UnionToIntersection } from './utils' +import { Expand, UnionToIntersection, UnionToTuple } from './utils' export type ParseRoute = | TRouteTree @@ -59,9 +59,23 @@ export type RoutePaths = | ParseRoute['fullPath'] | '/' +type UnionizeCollisions = { + [P in keyof T & keyof U]: T[P] extends U[P] ? T[P] : T[P] | U[P] +} +type Reducer> = C & + Omit & + Omit + +type Reduce = T extends [ + infer First, + ...infer Rest, +] + ? Reduce> + : Result + export type FullSearchSchema = Partial< Expand< - UnionToIntersection['types']['fullSearchSchema']> + Reduce['types']['fullSearchSchema']>> > > diff --git a/packages/react-router/src/utils.ts b/packages/react-router/src/utils.ts index 9ca840d17f3..e89ed43aafc 100644 --- a/packages/react-router/src/utils.ts +++ b/packages/react-router/src/utils.ts @@ -133,6 +133,16 @@ export type PickExclude = { [K in keyof T as T[K] extends U ? never : K]: T[K] } +// from https://github.com/type-challenges/type-challenges/issues/737 +type LastInUnion = UnionToIntersection< + U extends unknown ? (x: U) => 0 : never +> extends (x: infer L) => 0 + ? L + : never +export type UnionToTuple> = [U] extends [never] + ? [] + : [...UnionToTuple>, Last] + // export const isServer = typeof document === 'undefined'