Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

feat(router): router events type inference #23753

Closed
wants to merge 4 commits into from
Closed
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
14 changes: 11 additions & 3 deletions packages/next/client/router.ts
Original file line number Diff line number Diff line change
Expand Up @@ -17,6 +17,14 @@ export { Router, NextRouter }

export type SingletonRouter = SingletonRouterBase & NextRouter

export type RouterEvent =
| 'routeChangeStart'
| 'beforeHistoryChange'
| 'routeChangeComplete'
| 'routeChangeError'
| 'hashChangeStart'
| 'hashChangeComplete'

const singletonRouter: SingletonRouterBase = {
router: null, // holds the actual router instance
readyCallbacks: [],
Expand Down Expand Up @@ -44,7 +52,7 @@ const urlPropertyFields = [
'isPreview',
'isLocaleDomain',
]
const routerEvents = [
const routerEvents: RouterEvent[] = [
'routeChangeStart',
'beforeHistoryChange',
'routeChangeComplete',
Expand Down Expand Up @@ -89,9 +97,9 @@ coreMethodFields.forEach((field: string) => {
}
})

routerEvents.forEach((event: string) => {
routerEvents.forEach((event) => {
singletonRouter.ready(() => {
Router.events.on(event, (...args) => {
Router.events.on(event as any, (...args: any[]) => {
const eventField = `on${event.charAt(0).toUpperCase()}${event.substring(
1
)}`
Expand Down
11 changes: 7 additions & 4 deletions packages/next/next-server/lib/mitt.ts
Original file line number Diff line number Diff line change
Expand Up @@ -16,10 +16,13 @@ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLI

type Handler = (...evts: any[]) => void

export type MittEmitter = {
on(type: string, handler: Handler): void
off(type: string, handler: Handler): void
emit(type: string, ...evts: any[]): void
export type MittEmitter<
Type extends string = string,
Func extends Handler = Handler
> = {
on(type: Type, handler: Func): void
off(type: Type, handler: Func): void
emit(type: Type, ...evts: any[]): void
}

export default function mitt(): MittEmitter {
Expand Down
18 changes: 16 additions & 2 deletions packages/next/next-server/lib/router/router.ts
Original file line number Diff line number Diff line change
Expand Up @@ -13,6 +13,7 @@ import {
isAssetError,
markAssetError,
} from '../../../client/route-loader'
import { RouterEvent } from '../../../client/router'
import { DomainLocales } from '../../server/config'
import { denormalizePagePath } from '../../server/denormalize-page-path'
import { normalizeLocalePath } from '../i18n/normalize-locale-path'
Expand Down Expand Up @@ -424,6 +425,19 @@ type ComponentLoadCancel = (() => void) | null

type HistoryMethod = 'replaceState' | 'pushState'

type RouterEventEmitter = MittEmitter<
Exclude<RouterEvent, 'routeChangeError'>,
(url: string, routeProps: { shallow: boolean }) => void
> &
MittEmitter<
'routeChangeError',
(
err: Error & { cancelled: boolean },
url: string,
routeProps: { shallow: boolean }
) => void
>

const manualScrollRestoration =
process.env.__NEXT_SCROLL_RESTORATION &&
typeof window !== 'undefined' &&
Expand Down Expand Up @@ -504,7 +518,7 @@ export default class Router implements BaseRouter {
clc: ComponentLoadCancel
pageLoader: any
_bps: BeforePopStateCallback | undefined
events: MittEmitter
events: RouterEventEmitter = mitt()
_wrapApp: (App: AppComponent) => any
isSsr: boolean
isFallback: boolean
Expand All @@ -520,7 +534,7 @@ export default class Router implements BaseRouter {

private _idx: number = 0

static events: MittEmitter = mitt()
static events: RouterEventEmitter = mitt()

constructor(
pathname: string,
Expand Down