diff --git a/packages/next/client/index.tsx b/packages/next/client/index.tsx index 080eae4cbaed6..32b6558c42b88 100644 --- a/packages/next/client/index.tsx +++ b/packages/next/client/index.tsx @@ -259,7 +259,7 @@ class Container extends React.Component<{ } } -export const emitter: MittEmitter = mitt() +export const emitter: MittEmitter = mitt() let CachedComponent: React.ComponentType export default async (opts: { webpackHMR?: any } = {}) => { diff --git a/packages/next/client/router.ts b/packages/next/client/router.ts index ca4c5287f6bf4..b52e5e3990db2 100644 --- a/packages/next/client/router.ts +++ b/packages/next/client/router.ts @@ -52,7 +52,9 @@ const routerEvents = [ 'routeChangeError', 'hashChangeStart', 'hashChangeComplete', -] +] as const +export type RouterEvent = typeof routerEvents[number] + const coreMethodFields = [ 'push', 'replace', @@ -90,7 +92,7 @@ coreMethodFields.forEach((field: string) => { } }) -routerEvents.forEach((event: string) => { +routerEvents.forEach((event) => { singletonRouter.ready(() => { Router.events.on(event, (...args) => { const eventField = `on${event.charAt(0).toUpperCase()}${event.substring( diff --git a/packages/next/next-server/lib/mitt.ts b/packages/next/next-server/lib/mitt.ts index e7c57c33b6e6c..ca447df78f48b 100644 --- a/packages/next/next-server/lib/mitt.ts +++ b/packages/next/next-server/lib/mitt.ts @@ -16,13 +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 = { + on(type: T, handler: Handler): void + off(type: T, handler: Handler): void + emit(type: T, ...evts: any[]): void } -export default function mitt(): MittEmitter { +export default function mitt(): MittEmitter { const all: { [s: string]: Handler[] } = Object.create(null) return { diff --git a/packages/next/next-server/lib/router/router.ts b/packages/next/next-server/lib/router/router.ts index 75ac430c4cf11..c915f38c1d8d8 100644 --- a/packages/next/next-server/lib/router/router.ts +++ b/packages/next/next-server/lib/router/router.ts @@ -12,6 +12,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' @@ -522,7 +523,7 @@ export default class Router implements BaseRouter { clc: ComponentLoadCancel pageLoader: any _bps: BeforePopStateCallback | undefined - events: MittEmitter + events: MittEmitter _wrapApp: (App: AppComponent) => any isSsr: boolean isFallback: boolean @@ -538,7 +539,7 @@ export default class Router implements BaseRouter { private _idx: number = 0 - static events: MittEmitter = mitt() + static events: MittEmitter = mitt() constructor( pathname: string, diff --git a/test/integration/typescript/components/router.tsx b/test/integration/typescript/components/router.tsx index c33df8403d859..3e68bb0a30a92 100644 --- a/test/integration/typescript/components/router.tsx +++ b/test/integration/typescript/components/router.tsx @@ -4,12 +4,16 @@ import Router, { withRouter } from 'next/router' export default withRouter(({ router }) => { React.useEffect(() => { + Router.events.on('routeChangeComplete', () => {}) + //@ts-expect-error Router.events.on('event', () => {}) Router.prefetch('/page') Router.push Router.back Router.reload + router.events.on('routeChangeComplete', () => {}) + //@ts-expect-error router.events.on('event', () => {}) router.prefetch('/page') router.push