Skip to content

Commit

Permalink
refactor: revert the complex types for path parsing
Browse files Browse the repository at this point in the history
Achieve it with a build plugin instead; https://github.com/posva/unplugin-vue-router
Types were too slow due to their recursive nature and relying on tuples
too much. A build-time type generation is not only reliable and fast but
also enable creating other patterns.
  • Loading branch information
posva committed Jun 30, 2022
1 parent 411bc3d commit 06aefa8
Show file tree
Hide file tree
Showing 13 changed files with 38 additions and 882 deletions.
28 changes: 8 additions & 20 deletions packages/router/src/RouterLink.ts
Original file line number Diff line number Diff line change
Expand Up @@ -31,36 +31,26 @@ import {
VueUseOptions,
RouteLocation,
RouteLocationNormalized,
RouteLocationPathRaw,
RouteLocationString,
RouteLocationNamedRaw,
} from './types'
import { isSameRouteLocationParams, isSameRouteRecord } from './location'
import { routerKey, routeLocationKey } from './injectionSymbols'
import { RouteRecord } from './matcher/types'
import { NavigationFailure } from './errors'
import { isArray, isBrowser, noop } from './utils'
import type { Router } from './router'
import type { RouteNamedMap, RouteStaticPathMap } from './types/named'
import type { RouterTyped } from './typedRouter'

export interface RouterLinkOptions<
Routes extends RouteLocationRaw = RouteLocationRaw
> {
export interface RouterLinkOptions {
/**
* Route Location the link should navigate to when clicked on.
*/
to: Routes
to: RouteLocationRaw
/**
* Calls `router.replace` instead of `router.push`.
*/
replace?: boolean
// TODO: refactor using extra options allowed in router.push. Needs RFC
}

export interface RouterLinkProps<
Routes extends RouteLocationRaw = RouteLocationRaw
> extends RouterLinkOptions<Routes> {
export interface RouterLinkProps extends RouterLinkOptions {
/**
* Whether RouterLink should not wrap its content in an `a` tag. Useful when
* using `v-slot` to create a custom RouterLink
Expand Down Expand Up @@ -261,22 +251,20 @@ export const RouterLinkImpl = /*#__PURE__*/ defineComponent({
/**
* Component to render a link that triggers a navigation on click.
*/
export const RouterLink: RouterLinkTyped = RouterLinkImpl as any
export const RouterLink: _RouterLinkI = RouterLinkImpl as any

/**
* Typed version of the `RouterLink` component. Its generic defaults to the typed router so it can be inferred
* automatically for JSX.
*
* @internal
*/
export interface RouterLinkTyped<R extends Router = RouterTyped> {
export interface _RouterLinkI {
new (): {
$props: AllowedComponentProps &
ComponentCustomProps &
VNodeProps &
RouterLinkProps<
| RouteLocationNamedRaw<RouteNamedMap<R['options']['routes']>>
| RouteLocationString<RouteStaticPathMap<R['options']['routes']>>
| RouteLocationPathRaw<RouteStaticPathMap<R['options']['routes']>>
>
RouterLinkProps

$slots: {
default: (arg: UnwrapRef<ReturnType<typeof useLink>>) => VNode[]
Expand Down
8 changes: 4 additions & 4 deletions packages/router/src/globalExtensions.ts
Original file line number Diff line number Diff line change
Expand Up @@ -4,8 +4,8 @@ import type {
RouteLocationNormalizedLoaded,
} from './types'
import { RouterView } from './RouterView'
import type { RouterLinkTyped } from './RouterLink'
import type { RouterTyped } from './typedRouter'
import { RouterLink } from './RouterLink'
import type { Router } from './router'

declare module '@vue/runtime-core' {
export interface ComponentCustomOptions {
Expand Down Expand Up @@ -55,11 +55,11 @@ declare module '@vue/runtime-core' {
/**
* {@link Router} instance used by the application.
*/
$router: RouterTyped
$router: Router
}

export interface GlobalComponents {
RouterView: typeof RouterView
RouterLink: RouterLinkTyped<RouterTyped>
RouterLink: typeof RouterLink
}
}
23 changes: 1 addition & 22 deletions packages/router/src/index.ts
Original file line number Diff line number Diff line change
Expand Up @@ -46,7 +46,6 @@ export type {
RouteParamValueRaw,
RouteLocationNamedRaw,
RouteLocationPathRaw,
RouteLocationString,
RouteLocationMatched,
RouteLocationOptions,
RouteRecordRedirectOption,
Expand All @@ -62,26 +61,6 @@ export type {
NavigationGuardWithThis,
NavigationHookAfter,
} from './types'
export type {
ParamsFromPath,
ParamsRawFromPath,
_StripRegex,
_RemoveUntilClosingPar,
_ExtractParamsOfPath,
_ParamExtractResult,
_ExtractModifier,
_ModifierExtracTResult,
_JoinPath,
_ParamDelimiter,
_ParamModifier,
} from './types/paths'
export type {
RouteNamedMap,
RouteStaticPathMap,
RouteNamedInfo,
_RouteRecordNamedBaseInfo,
} from './types/named'
export type { Config, RouterTyped } from './typedRouter'

export { createRouter } from './router'
export type { Router, RouterOptions, RouterScrollBehavior } from './router'
Expand All @@ -100,9 +79,9 @@ export {
} from './navigationGuards'
export { RouterLink, useLink } from './RouterLink'
export type {
_RouterLinkI,
RouterLinkProps,
UseLinkOptions,
RouterLinkTyped,
} from './RouterLink'
export { RouterView } from './RouterView'
export type { RouterViewProps } from './RouterView'
Expand Down
8 changes: 3 additions & 5 deletions packages/router/src/injectionSymbols.ts
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
import { InjectionKey, ComputedRef, Ref } from 'vue'
import type { InjectionKey, ComputedRef, Ref } from 'vue'
import { RouteLocationNormalizedLoaded } from './types'
import { RouteRecordNormalized } from './matcher/types'
import { RouterTyped } from './typedRouter'
import type { Router } from './router'

/**
* RouteRecord being rendered by the closest ancestor Router View. Used for
Expand Down Expand Up @@ -30,9 +30,7 @@ export const viewDepthKey = Symbol(
*
* @internal
*/
export const routerKey = Symbol(
__DEV__ ? 'router' : ''
) as InjectionKey<RouterTyped>
export const routerKey = Symbol(__DEV__ ? 'router' : '') as InjectionKey<Router>

/**
* Allows overriding the current route returned by `useRoute` in tests. rl
Expand Down
30 changes: 7 additions & 23 deletions packages/router/src/router.ts
Original file line number Diff line number Diff line change
Expand Up @@ -13,9 +13,6 @@ import {
RouteLocationOptions,
MatcherLocationRaw,
RouteParams,
RouteLocationNamedRaw,
RouteLocationPathRaw,
RouteLocationString,
} from './types'
import { RouterHistory, HistoryState, NavigationType } from './history/common'
import {
Expand Down Expand Up @@ -71,7 +68,6 @@ import {
routerViewLocationKey,
} from './injectionSymbols'
import { addDevtools } from './devtools'
import { RouteNamedMap, RouteStaticPathMap } from './types/named'

/**
* Internal type to define an ErrorHandler
Expand Down Expand Up @@ -185,9 +181,9 @@ export interface RouterOptions extends PathParserOptions {
}

/**
* Router instance. **The `Options` generic is internal**.
* Router instance.
*/
export interface Router<Options extends RouterOptions = RouterOptions> {
export interface Router {
/**
* @internal
*/
Expand All @@ -199,7 +195,7 @@ export interface Router<Options extends RouterOptions = RouterOptions> {
/**
* Original options object passed to create the Router
*/
readonly options: Options
readonly options: RouterOptions

/**
* Allows turning off the listening of history events. This is a low level api for micro-frontends.
Expand Down Expand Up @@ -256,25 +252,15 @@ export interface Router<Options extends RouterOptions = RouterOptions> {
*
* @param to - Route location to navigate to
*/
push(
to:
| RouteLocationNamedRaw<RouteNamedMap<Options['routes']>>
| RouteLocationString<RouteStaticPathMap<Options['routes']>>
| RouteLocationPathRaw<RouteStaticPathMap<Options['routes']>>
): Promise<NavigationFailure | void | undefined>
push(to: RouteLocationRaw): Promise<NavigationFailure | void | undefined>

/**
* Programmatically navigate to a new URL by replacing the current entry in
* the history stack.
*
* @param to - Route location to navigate to
*/
replace(
to:
| RouteLocationNamedRaw<RouteNamedMap<Options['routes']>>
| RouteLocationString<RouteStaticPathMap<Options['routes']>>
| RouteLocationPathRaw<RouteStaticPathMap<Options['routes']>>
): Promise<NavigationFailure | void | undefined>
replace(to: RouteLocationRaw): Promise<NavigationFailure | void | undefined>

/**
* Go back in history if possible by calling `history.back()`. Equivalent to
Expand Down Expand Up @@ -373,9 +359,7 @@ export interface Router<Options extends RouterOptions = RouterOptions> {
*
* @param options - {@link RouterOptions}
*/
export function createRouter<Options extends RouterOptions>(
options: Options
): Router<Options> {
export function createRouter(options: RouterOptions): Router {
const matcher = createRouterMatcher(options.routes, options)
const parseQuery = options.parseQuery || originalParseQuery
const stringifyQuery = options.stringifyQuery || originalStringifyQuery
Expand Down Expand Up @@ -1173,7 +1157,7 @@ export function createRouter<Options extends RouterOptions>(
let started: boolean | undefined
const installedApps = new Set<App>()

const router: Router<Options> = {
const router: Router = {
currentRoute,
listening: true,

Expand Down
28 changes: 0 additions & 28 deletions packages/router/src/typedRouter.ts

This file was deleted.

75 changes: 13 additions & 62 deletions packages/router/src/types/index.ts
Original file line number Diff line number Diff line change
Expand Up @@ -4,12 +4,6 @@ import { Ref, ComponentPublicInstance, Component, DefineComponent } from 'vue'
import { RouteRecord, RouteRecordNormalized } from '../matcher/types'
import { HistoryState } from '../history/common'
import { NavigationFailure } from '../errors'
import {
RouteNamedInfo,
RouteNamedMapGeneric,
RouteStaticPathMapGeneric,
} from './named'
import { LiteralUnion } from './utils'

export type Lazy<T> = () => Promise<T>
export type Override<T, U> = Pick<T, Exclude<keyof T, keyof U>> & U
Expand Down Expand Up @@ -73,25 +67,16 @@ export interface MatcherLocationAsName {
/**
* @internal
*/
export interface LocationAsRelativeRaw<
Name extends RouteRecordName = RouteRecordName,
Info extends RouteNamedInfo = RouteNamedInfo
> {
name?: Name
params?: Info extends RouteNamedInfo<any, any, infer ParamsRaw>
? ParamsRaw
: RouteParamsRaw
export interface LocationAsRelativeRaw {
name?: string
params?: RouteParamsRaw
}

/**
* @internal
*/
export interface MatcherLocationAsRelative<
Info extends RouteNamedInfo = RouteNamedInfo
> {
params?: Info extends RouteNamedInfo<any, infer Params, any>
? Params
: RouteParams
export interface MatcherLocationAsRelative {
params?: RouteParams
}

/**
Expand Down Expand Up @@ -124,59 +109,25 @@ export type RouteLocationRaw =
| RouteLocationPathRaw
| RouteLocationNamedRaw

/**
* Route location that can infer full path locations
*
* @internal
*/
export type RouteLocationString<
RouteMap extends RouteStaticPathMapGeneric = RouteStaticPathMapGeneric
> = RouteStaticPathMapGeneric extends RouteMap
? string
: LiteralUnion<
{
[K in keyof RouteMap]: RouteMap[K]
}[keyof RouteMap],
string
>

/**
* Route Location that can infer the necessary params based on the name.
*
* @internal
*/
export type RouteLocationNamedRaw<
RouteMap extends RouteNamedMapGeneric = RouteNamedMapGeneric
> = RouteNamedMapGeneric extends RouteMap
? // allows assigning a RouteLocationRaw to RouteLocationNamedRaw
RouteQueryAndHash & LocationAsRelativeRaw & RouteLocationOptions
: {
[K in Extract<keyof RouteMap, RouteRecordName>]: LocationAsRelativeRaw<
K,
RouteMap[K]
>
}[Extract<keyof RouteMap, RouteRecordName>] &
RouteQueryAndHash &
RouteLocationOptions
export interface RouteLocationNamedRaw
extends RouteQueryAndHash,
LocationAsRelativeRaw,
RouteLocationOptions {}

/**
* Route Location that can infer the possible paths.
*
* @internal
*/
export type RouteLocationPathRaw<
RouteMap extends RouteStaticPathMapGeneric = RouteStaticPathMapGeneric
> = RouteStaticPathMapGeneric extends RouteMap
? // allows assigning a RouteLocationRaw to RouteLocationPath
RouteQueryAndHash & MatcherLocationAsPath & RouteLocationOptions
: RouteQueryAndHash &
RouteLocationOptions &
MatcherLocationAsPath<
LiteralUnion<
{ [K in keyof RouteMap]: RouteMap[K] }[keyof RouteMap],
string
>
>
export interface RouteLocationPathRaw
extends RouteQueryAndHash,
MatcherLocationAsPath,
RouteLocationOptions {}

export interface RouteLocationMatched extends RouteRecordNormalized {
// components cannot be Lazy<RouteComponent>
Expand Down
Loading

0 comments on commit 06aefa8

Please sign in to comment.