Skip to content

Commit

Permalink
Further simplify types
Browse files Browse the repository at this point in the history
  • Loading branch information
dgieselaar committed Jan 23, 2022
1 parent f6d7da1 commit 213501c
Show file tree
Hide file tree
Showing 4 changed files with 63 additions and 81 deletions.
51 changes: 20 additions & 31 deletions packages/kbn-typed-react-router-config/src/create_router.test.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -10,16 +10,13 @@ import * as t from 'io-ts';
import { toNumberRt } from '@kbn/io-ts-utils';
import { createRouter } from './create_router';
import { createMemoryHistory } from 'history';
import { route } from './route';

describe('createRouter', () => {
const routes = route([
{
path: '/',
const routes = {
'/': {
element: <></>,
children: [
{
path: '/',
children: {
'/': {
element: <></>,
params: t.type({
query: t.type({
Expand All @@ -32,45 +29,39 @@ describe('createRouter', () => {
rangeFrom: 'now-30m',
},
},
children: [
{
path: '/services/{serviceName}/errors',
children: {
'/services/{serviceName}/errors': {
element: <></>,
params: t.type({
path: t.type({
serviceName: t.string,
}),
}),
children: [
{
path: '/services/{serviceName}/errors/{groupId}',
children: {
'/services/{serviceName}/errors/{groupId}': {
element: <></>,
params: t.type({
path: t.type({ groupId: t.string }),
}),
},
{
path: '/services/{serviceName}/errors',
'/services/{serviceName}/errors': {
element: <></>,
},
],
},
},
{
path: '/services',
'/services': {
element: <></>,
params: t.type({
query: t.type({
transactionType: t.string,
}),
}),
},
{
path: '/services/{serviceName}',
'/services/{serviceName}': {
element: <></>,
children: [
{
children: {
'/services/{serviceName}': {
element: <></>,
path: '/services/{serviceName}',
params: t.type({
path: t.type({
serviceName: t.string,
Expand All @@ -81,10 +72,9 @@ describe('createRouter', () => {
}),
}),
},
],
},
},
{
path: '/traces',
'/traces': {
element: <></>,
params: t.type({
query: t.type({
Expand All @@ -93,20 +83,19 @@ describe('createRouter', () => {
}),
}),
},
{
path: '/service-map',
'/service-map': {
element: <></>,
params: t.type({
query: t.type({
maxNumNodes: t.string.pipe(toNumberRt as any),
}),
}),
},
],
},
},
],
},
},
] as const);
};

let history = createMemoryHistory();
const router = createRouter(routes);
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -37,7 +37,7 @@ export function createRouter<TRoutes extends RouteMap>(routes: TRoutes): Router<
Object.entries((route.children as RouteMap | undefined) ?? {})?.map(([path, child]) =>
toReactRouterConfigRoute({ ...child, path })
) ?? [],
exact: !route.children?.length,
exact: !route.children || Object.values(route.children).length === 0,
path: toReactRouterPath(route.path),
};

Expand Down
90 changes: 42 additions & 48 deletions packages/kbn-typed-react-router-config/src/types/index.ts
Original file line number Diff line number Diff line change
Expand Up @@ -12,7 +12,14 @@ import { ReactElement } from 'react';
import { RequiredKeys, ValuesType, UnionToIntersection } from 'utility-types';
import { NormalizePath } from './utils';

export type PathsOf<TRouteMap extends RouteMap> = keyof MapRoutes<TRouteMap> & string;
export type PathsOf<TRouteMap extends RouteMap> = string &
ValuesType<{
[key in keyof TRouteMap]:
| key
| (TRouteMap[key] extends { children: RouteMap }
? AppendPath<key & string, '*'> | PathsOf<TRouteMap[key]['children']>
: never);
}>;

export type RouteMap = Record<string, Route>;

Expand Down Expand Up @@ -42,71 +49,55 @@ export interface RouteMatch<TRoute extends Route = Route> {
};
}

type ToRouteMatch<TRoutes extends Route[]> = TRoutes extends []
? []
: TRoutes extends [Route]
type ToRouteMatch<TRoutes extends Route[]> = TRoutes extends [Route]
? [RouteMatch<TRoutes[0]>]
: TRoutes extends [Route, ...infer TTail]
? TTail extends Route[]
? [RouteMatch<TRoutes[0]>, ...ToRouteMatch<TTail>]
: []
: [];

type UnwrapRouteMap<TRoute extends Route & { parents?: Route[] }> = TRoute extends {
parents: Route[];
}
? ToRouteMatch<[...TRoute['parents'], Omit<TRoute, 'parents'>]>
: ToRouteMatch<[Omit<TRoute, 'parents'>]>;
: TRoutes extends [Route, ...infer TNextRoutes]
? [RouteMatch<TRoutes[0]>, ...(TNextRoutes extends Route[] ? ToRouteMatch<TNextRoutes> : [])]
: TRoutes extends []
? []
: never;

export type Match<TRoutes extends RouteMap, TPath extends string> = MapRoutes<TRoutes> extends {
[key in TPath]: Route;
}
? UnwrapRouteMap<MapRoutes<TRoutes>[TPath]>
: [];
export type Match<TRoutes extends RouteMap, TPath extends string> = MapRoutes<TRoutes>[TPath];

export interface DefaultOutput {
path: {};
query: {};
}

type OutputOfRouteMatch<TRouteMatch extends RouteMatch> = TRouteMatch extends {
route: { params: t.Type<any> };
type OutputOfRoute<TRoute extends Route> = TRoute extends {
params: t.Type<any>;
}
? t.OutputOf<TRouteMatch['route']['params']>
: DefaultOutput;
? t.OutputOf<TRoute['params']>
: {};

type OutputOfMatches<TRouteMatches extends RouteMatch[]> = TRouteMatches extends [RouteMatch]
? OutputOfRouteMatch<TRouteMatches[0]>
: TRouteMatches extends [RouteMatch, ...infer TNextRouteMatches]
? OutputOfRouteMatch<TRouteMatches[0]> &
(TNextRouteMatches extends RouteMatch[] ? OutputOfMatches<TNextRouteMatches> : DefaultOutput)
: TRouteMatches extends RouteMatch[]
? OutputOfRouteMatch<ValuesType<TRouteMatches>>
: DefaultOutput;
type OutputOfRoutes<TRoutes extends Route[]> = TRoutes extends [Route]
? OutputOfRoute<TRoutes[0]>
: TRoutes extends [Route, ...infer TNextRoutes]
? OutputOfRoute<TRoutes[0]> & (TNextRoutes extends Route[] ? OutputOfRoutes<TNextRoutes> : {})
: {};

export type OutputOf<TRoutes extends RouteMap, TPath extends PathsOf<TRoutes>> = OutputOfMatches<
export type OutputOf<TRoutes extends RouteMap, TPath extends PathsOf<TRoutes>> = OutputOfRoutes<
Match<TRoutes, TPath>
> &
DefaultOutput;

type TypeOfRouteMatch<TRouteMatch extends RouteMatch> = TRouteMatch extends {
route: { params: t.Type<any> };
type TypeOfRoute<TRoute extends Route> = TRoute extends {
params: t.Type<any>;
}
? t.TypeOf<TRouteMatch['route']['params']>
? t.TypeOf<TRoute['params']>
: {};

type TypeOfMatches<TRouteMatches extends RouteMatch[]> = TRouteMatches extends [RouteMatch]
? TypeOfRouteMatch<TRouteMatches[0]>
: TRouteMatches extends [RouteMatch, ...infer TNextRouteMatches]
? TypeOfRouteMatch<TRouteMatches[0]> &
(TNextRouteMatches extends RouteMatch[] ? TypeOfMatches<TNextRouteMatches> : {})
type TypeOfRoutes<TRoutes extends Route[]> = TRoutes extends [Route]
? TypeOfRoute<TRoutes[0]>
: TRoutes extends [Route, ...infer TNextRoutes]
? TypeOfRoute<TRoutes[0]> & (TNextRoutes extends Route[] ? TypeOfRoutes<TNextRoutes> : {})
: {};

export type TypeOf<
TRoutes extends RouteMap,
TPath extends PathsOf<TRoutes>,
TWithDefaultOutput extends boolean = true
> = TypeOfMatches<Match<TRoutes, TPath>> & (TWithDefaultOutput extends true ? DefaultOutput : {});
> = TypeOfRoutes<Match<TRoutes, TPath>> & (TWithDefaultOutput extends true ? DefaultOutput : {});

export type TypeAsArgs<TObject> = keyof TObject extends never
? []
Expand All @@ -122,8 +113,8 @@ export interface Router<TRoutes extends RouteMap> {
matchRoutes<TPath extends PathsOf<TRoutes>>(
path: TPath,
location: Location
): Match<TRoutes, TPath>;
matchRoutes(location: Location): Match<TRoutes, PathsOf<TRoutes>>;
): ToRouteMatch<Match<TRoutes, TPath>>;
matchRoutes(location: Location): ToRouteMatch<Match<TRoutes, PathsOf<TRoutes>>>;
getParams<TPath extends PathsOf<TRoutes>>(
path: TPath,
location: Location
Expand Down Expand Up @@ -168,7 +159,7 @@ type MaybeUnion<T extends Record<string, any>, U extends Record<string, any>> =

type MapRoute<TRoute extends RouteWithPath, TParents extends RouteWithPath[] = []> = MaybeUnion<
{
[key in TRoute['path']]: TRoute & { parents: TParents };
[key in TRoute['path']]: [...TParents, TRoute];
},
TRoute extends { children: RouteMap }
? MaybeUnion<
Expand All @@ -194,7 +185,7 @@ type FromRouteMap<
type MapRoutes<TRouteMap extends RouteMap, TParents extends RouteWithPath[] = []> = FromRouteMap<
TRouteMap,
TParents
> extends Record<string, any>
> extends Record<string, Route[]>
? FromRouteMap<TRouteMap, TParents>
: never;

Expand Down Expand Up @@ -384,7 +375,7 @@ type MapRoutes<TRouteMap extends RouteMap, TParents extends RouteWithPath[] = []
// type Mapped = MapRoutes<Routes>;
// type Paths = PathsOf<Routes>;

// type Bar = ValuesType<Match<Routes, '/*'>>['route']['path'];
// type Bar = Match<Routes, '/*'>;
// type Foo = OutputOf<Routes, '/*'>;
// type Baz = OutputOf<Routes, '/services/:serviceName/errors'>;

Expand All @@ -394,4 +385,7 @@ type MapRoutes<TRouteMap extends RouteMap, TParents extends RouteWithPath[] = []
// return {} as any;
// }

// const params = _useApmParams('/services/:serviceName/nodes/*');
// const {
// path: { serviceName },
// query: { comparisonType },
// } = _useApmParams('/services/:serviceName/nodes/*');
Original file line number Diff line number Diff line change
Expand Up @@ -19,7 +19,6 @@ export function BackendInventory() {
const {
query: { environment },
} = useApmParams('/backends');

const kueryBarBoolFilter = getKueryBarBoolFilter({
environment,
});
Expand Down

0 comments on commit 213501c

Please sign in to comment.