Skip to content

Commit 2eca469

Browse files
committed
refactor: optimised types
1 parent 7b81e87 commit 2eca469

File tree

1 file changed

+57
-35
lines changed

1 file changed

+57
-35
lines changed

packages/react-router/src/Matches.tsx

Lines changed: 57 additions & 35 deletions
Original file line numberDiff line numberDiff line change
@@ -27,62 +27,84 @@ import type {
2727
} from './routeInfo'
2828
import type { ControlledPromise, DeepPartial, NoInfer } from './utils'
2929

30-
export type MatchSuggestions<
31-
TValue,
32-
TParentPath extends string,
33-
> = TValue extends string | number | bigint | boolean | symbol
34-
? never
35-
: TValue extends ReadonlyArray<any>
36-
? `${TParentPath}${keyof TValue & `${number}`}`
37-
: `${TParentPath}${keyof TValue & string}`
38-
39-
export type FindMatchByKey<TMatch, TKey, TValue> = TValue extends any
40-
? TKey extends keyof TValue
41-
? TMatch
42-
: never
30+
export type AnyMatchAndValue = { match: any; value: any }
31+
32+
export type FindValueByKey<TKey, TValue> = TValue extends any
33+
? TValue[TKey & keyof TValue]
34+
: never
35+
36+
export type CreateMatchAndValue<TMatch, TValue> = TValue extends any
37+
? {
38+
match: TMatch
39+
value: TValue
40+
}
41+
: never
42+
43+
export type NextMatchAndValue<
44+
TKey,
45+
TMatchAndValue extends AnyMatchAndValue,
46+
> = TMatchAndValue extends any
47+
? CreateMatchAndValue<
48+
TMatchAndValue['match'],
49+
FindValueByKey<TKey, TMatchAndValue['value']>
50+
>
4351
: never
4452

45-
export type ValueOf<TKey, TValue> = TValue extends any
46-
? TKey extends keyof TValue
47-
? TValue[TKey]
53+
export type IsMatchKeyOf<TValue> =
54+
TValue extends ReadonlyArray<any>
55+
? keyof TValue & `${number}`
56+
: TValue extends object
57+
? keyof TValue & string
58+
: never
59+
60+
export type IsMatchPath<
61+
TParentPath extends string,
62+
TMatchAndValue extends AnyMatchAndValue,
63+
> = `${TParentPath}${IsMatchKeyOf<TMatchAndValue['value']>}`
64+
65+
export type IsMatchResult<
66+
TKey,
67+
TMatchAndValue extends AnyMatchAndValue,
68+
> = TMatchAndValue extends any
69+
? TKey extends keyof TMatchAndValue['value']
70+
? TMatchAndValue['match']
4871
: never
4972
: never
5073

51-
export type SuggestMatchByPath<
74+
export type IsMatchParse<
5275
TPath,
53-
TMatch,
54-
TValue = TMatch,
76+
TMatchAndValue extends AnyMatchAndValue,
5577
TParentPath extends string = '',
5678
> = TPath extends `${string}.${string}`
5779
? TPath extends `${infer TFirst}.${infer TRest}`
58-
? SuggestMatchByPath<
80+
? IsMatchParse<
5981
TRest,
60-
TMatch,
61-
ValueOf<TFirst, TValue>,
82+
NextMatchAndValue<TFirst, TMatchAndValue>,
6283
`${TParentPath}${TFirst}.`
6384
>
6485
: never
6586
: {
66-
suggestions: MatchSuggestions<TValue, TParentPath>
67-
match: FindMatchByKey<TMatch, TPath, TValue>
87+
path: IsMatchPath<TParentPath, TMatchAndValue>
88+
result: IsMatchResult<TPath, TMatchAndValue>
6889
}
6990

70-
export type SuggestMatchesByPath<TPath, TMatch> = TMatch extends any
71-
? SuggestMatchByPath<TPath, TMatch>
72-
: never
91+
export type IsMatch<TMatch, TPath> = IsMatchParse<
92+
TPath,
93+
TMatch extends any ? { match: TMatch; value: TMatch } : never
94+
>
7395

74-
export type ValidateMatchSuggestions<
75-
TMatch extends AnyRouteMatch,
96+
export type ValidateIsMatchPath<
97+
TMatch,
7698
TPath extends string,
77-
> = TPath extends SuggestMatchesByPath<TPath, TMatch>['suggestions']
99+
> = TPath extends IsMatch<TMatch, TPath>['path']
78100
? TPath
79-
: SuggestMatchesByPath<TPath, TMatch>['suggestions']
101+
: IsMatch<TMatch, TPath>['path']
80102

81-
export const isMatch = <TMatch extends AnyRouteMatch, TPath extends string>(
103+
export const isMatch = <TMatch, TPath extends string>(
82104
match: TMatch,
83-
path: ValidateMatchSuggestions<TMatch, TPath>,
84-
): match is SuggestMatchesByPath<TPath, TMatch>['match'] => {
85-
const parts = path.split('.')
105+
path: ValidateIsMatchPath<TMatch, TPath>,
106+
): match is IsMatch<TMatch, TPath>['result'] => {
107+
const parts = (path as string).split('.')
86108
let part
87109
let value: any = match
88110

0 commit comments

Comments
 (0)