Skip to content

Commit b94123c

Browse files
Luis Fernando Alvarez DTimer
authored andcommitted
Improve exported router types (#7853)
* Added the RouteUrl type and improved router types * Added more tests for router types * Add build test for typescript types * Add next-env.d.ts to the typescript test * Removed next-env.d.ts * Added next-env.d.ts to gitignore * Remove route url re-exports * renamed PublicRouterInstance to be NextRouter * export the Url type * Replaced BaseRouter with NextRouter in server/utils * Don't export the Url type * Update tsconfig.json
1 parent 13cf664 commit b94123c

File tree

13 files changed

+78
-30
lines changed

13 files changed

+78
-30
lines changed

.gitignore

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -19,6 +19,7 @@ coverage
1919

2020
# test output
2121
test/**/out*
22+
test/**/next-env.d.ts
2223
.DS_Store
2324

2425
# Editors
Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,3 +1,4 @@
11
import * as React from 'react'
2+
import { NextRouter } from './router/router'
23

3-
export const RouterContext: React.Context<any> = React.createContext(null)
4+
export const RouterContext = React.createContext<NextRouter>(null as any)

packages/next-server/lib/router/router.ts

Lines changed: 13 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -30,6 +30,18 @@ export type BaseRouter = {
3030
asPath: string
3131
}
3232

33+
export type NextRouter = BaseRouter &
34+
Pick<
35+
Router,
36+
| 'push'
37+
| 'replace'
38+
| 'reload'
39+
| 'back'
40+
| 'prefetch'
41+
| 'beforePopState'
42+
| 'events'
43+
>
44+
3345
type RouteInfo = {
3446
Component: ComponentType
3547
props?: any
@@ -56,6 +68,7 @@ export default class Router implements BaseRouter {
5668
clc: ComponentLoadCancel
5769
pageLoader: any
5870
_bps: BeforePopStateCallback | undefined
71+
events: MittEmitter
5972

6073
static events: MittEmitter = mitt()
6174

packages/next-server/lib/utils.ts

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -3,7 +3,7 @@ import { ServerResponse, IncomingMessage } from 'http'
33
import { ComponentType } from 'react'
44
import { ParsedUrlQuery } from 'querystring'
55
import { ManifestItem } from '../server/render'
6-
import { BaseRouter } from './router/router'
6+
import { NextRouter } from './router/router'
77

88
/**
99
* Types used by both next and next-server
@@ -97,7 +97,7 @@ export interface NextPageContext {
9797
asPath?: string
9898
}
9999

100-
export type AppContextType<R extends BaseRouter = BaseRouter> = {
100+
export type AppContextType<R extends NextRouter = NextRouter> = {
101101
Component: NextComponentType<NextPageContext>
102102
router: R
103103
ctx: NextPageContext
@@ -108,7 +108,7 @@ export type AppInitialProps = {
108108
}
109109

110110
export type AppPropsType<
111-
R extends BaseRouter = BaseRouter,
111+
R extends NextRouter = NextRouter,
112112
P = {}
113113
> = AppInitialProps & {
114114
Component: NextComponentType<NextPageContext, any, P>

packages/next-server/server/render.tsx

Lines changed: 6 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -2,7 +2,7 @@ import { IncomingMessage, ServerResponse } from 'http'
22
import { ParsedUrlQuery } from 'querystring'
33
import React from 'react'
44
import { renderToString, renderToStaticMarkup } from 'react-dom/server'
5-
import { BaseRouter } from '../lib/router/router'
5+
import { NextRouter } from '../lib/router/router'
66
import mitt, { MittEmitter } from '../lib/mitt'
77
import {
88
loadGetInitialProps,
@@ -45,11 +45,12 @@ function noRouter() {
4545
throw new Error(message)
4646
}
4747

48-
class ServerRouter implements BaseRouter {
48+
class ServerRouter implements NextRouter {
4949
route: string
5050
pathname: string
5151
query: ParsedUrlQuery
5252
asPath: string
53+
events: any
5354
// TODO: Remove in the next major version, as this would mean the user is adding event listeners in server-side `render` method
5455
static events: MittEmitter = mitt()
5556

@@ -60,23 +61,19 @@ class ServerRouter implements BaseRouter {
6061
this.asPath = as
6162
this.pathname = pathname
6263
}
63-
// @ts-ignore
64-
push() {
64+
push(): any {
6565
noRouter()
6666
}
67-
// @ts-ignore
68-
replace() {
67+
replace(): any {
6968
noRouter()
7069
}
71-
// @ts-ignore
7270
reload() {
7371
noRouter()
7472
}
7573
back() {
7674
noRouter()
7775
}
78-
// @ts-ignore
79-
prefetch() {
76+
prefetch(): any {
8077
noRouter()
8178
}
8279
beforePopState() {

packages/next/client/router.ts

Lines changed: 4 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,6 @@
11
/* global window */
22
import React from 'react'
3-
import Router, { BaseRouter } from 'next-server/dist/lib/router/router'
3+
import Router, { NextRouter } from 'next-server/dist/lib/router/router'
44
import { RouterContext } from 'next-server/dist/lib/router-context'
55
import { RequestContext } from 'next-server/dist/lib/request-context'
66

@@ -14,17 +14,9 @@ type SingletonRouterBase = {
1414
ready(cb: () => any): void
1515
}
1616

17-
export { Router }
17+
export { Router, NextRouter }
1818

19-
export type PublicRouterInstance = BaseRouter &
20-
Pick<
21-
Router,
22-
'push' | 'replace' | 'reload' | 'back' | 'prefetch' | 'beforePopState'
23-
> & {
24-
events: typeof Router['events']
25-
}
26-
27-
export type SingletonRouter = SingletonRouterBase & PublicRouterInstance
19+
export type SingletonRouter = SingletonRouterBase & NextRouter
2820

2921
const singletonRouter: SingletonRouterBase = {
3022
router: null, // holds the actual router instance
@@ -146,7 +138,7 @@ export const createRouter = (...args: RouterArgs) => {
146138
}
147139

148140
// This function is used to create the `withRouter` router instance
149-
export function makePublicRouterInstance(router: Router): PublicRouterInstance {
141+
export function makePublicRouterInstance(router: Router): NextRouter {
150142
const _router = router as any
151143
const instance = {} as any
152144

packages/next/client/with-router.tsx

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,10 +1,10 @@
11
import React from 'react'
22
import PropTypes from 'prop-types'
33
import { NextComponentType, NextPageContext } from 'next-server/dist/lib/utils'
4-
import { PublicRouterInstance } from './router'
4+
import { NextRouter } from './router'
55

66
export type WithRouterProps = {
7-
router: PublicRouterInstance
7+
router: NextRouter
88
}
99

1010
export type ExcludeRouterProps<P> = Pick<

packages/next/lib/data.ts

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -26,7 +26,7 @@ export function createHook(
2626
throw new Error('key not provided to createHook options.')
2727
}
2828
return function useData(...args: Array<string | number>) {
29-
const router: import('next-server/lib/router/router').default = useContext(
29+
const router: import('next-server/lib/router/router').NextRouter = useContext(
3030
RouterContext
3131
)
3232
const dataManager: import('next-server/lib/data-manager').DataManager = useContext(
Lines changed: 19 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,19 @@
1+
import React from 'react'
2+
import Router, { withRouter } from 'next/router'
3+
4+
export default withRouter(({ router }) => {
5+
React.useEffect(() => {
6+
Router.events.on('event', () => {})
7+
Router.prefetch('/page')
8+
Router.push
9+
Router.back
10+
Router.reload
11+
12+
router.events.on('event', () => {})
13+
router.prefetch('/page')
14+
router.push
15+
router.back
16+
router.reload
17+
})
18+
return <>{router.pathname}</>
19+
})
Lines changed: 5 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,13 +1,17 @@
11
import React from 'react'
2+
import { useRouter } from 'next/router'
23
import { hello } from '../components/hello'
34
import { World } from '../components/world'
5+
import Router from '../components/router'
46

57
export default function HelloPage(): JSX.Element {
6-
// TEST: verify process.browser extension works
8+
const router = useRouter()
79
console.log(process.browser)
10+
console.log(router.pathname)
811
return (
912
<div>
1013
{hello()} <World />
14+
<Router />
1115
</div>
1216
)
1317
}

0 commit comments

Comments
 (0)