Merge pull request #28047 from kaw2k/master

Adds generic Query parameter to next.js's router
This commit is contained in:
Daniel Rosenwasser
2018-08-24 10:26:49 -07:00
committed by GitHub
4 changed files with 45 additions and 29 deletions
+8 -8
View File
@@ -1,19 +1,19 @@
import * as React from "react";
import { NextContext } from ".";
import { RouterProps } from "./router";
import { RouterProps, DefaultQuery } from "./router";
export interface AppComponentProps {
export interface AppComponentProps<Q = DefaultQuery> {
Component: React.ComponentType<any>;
router: RouterProps;
router: RouterProps<Q>;
pageProps: any;
}
export interface AppComponentContext {
export interface AppComponentContext<Q = DefaultQuery> {
Component: React.ComponentType<any>;
router: RouterProps;
ctx: NextContext;
router: RouterProps<Q>;
ctx: NextContext<Q>;
}
export class Container extends React.Component {}
export class Container extends React.Component { }
export default class App<TProps = {}> extends React.Component<TProps & AppComponentProps> {}
export default class App<TProps = {}, Q = DefaultQuery> extends React.Component<TProps & AppComponentProps<Q>> { }
+5 -5
View File
@@ -24,11 +24,11 @@ declare namespace next {
* Context object used in methods like `getInitialProps()`
* <<https://github.com/zeit/next.js/issues/1651>>
*/
interface NextContext {
interface NextContext<Q = QueryStringMapObject> {
/** path section of URL */
pathname: string;
/** query string section of URL parsed as an object */
query: QueryStringMapObject;
query: Q;
/** String of the actual path (including the query) shows in the browser */
asPath: string;
/** HTTP request object (server only) */
@@ -43,10 +43,10 @@ declare namespace next {
isServer?: boolean;
}
type NextSFC<TProps = {}> = NextStatelessComponent<TProps>;
interface NextStatelessComponent<TProps = {}>
type NextSFC<TProps = {}, Q = QueryStringMapObject> = NextStatelessComponent<TProps, Q>;
interface NextStatelessComponent<TProps = {}, Q = QueryStringMapObject>
extends React.StatelessComponent<TProps> {
getInitialProps?: (ctx: NextContext) => Promise<TProps>;
getInitialProps?: (ctx: NextContext<Q>) => Promise<TProps>;
}
type UrlLike = url.UrlObject | url.Url;
+22 -16
View File
@@ -26,20 +26,22 @@ export type PopStateCallback = (state: any) => boolean | undefined;
export type RouterCallback = () => void;
export interface RouterProps {
export interface DefaultQuery {
[key: string]:
| boolean
| boolean[]
| number
| number[]
| string
| string[];
}
export interface RouterProps<Q = DefaultQuery> {
// url property fields
readonly pathname: string;
readonly route: string;
readonly asPath?: string;
readonly query?: {
[key: string]:
| boolean
| boolean[]
| number
| number[]
| string
| string[];
};
readonly query?: Q;
// property fields
readonly components: {
@@ -78,18 +80,22 @@ export interface RouterProps {
};
}
export interface SingletonRouter extends RouterProps {
router: RouterProps | null;
export interface SingletonRouter<Q = DefaultQuery> extends RouterProps<Q> {
router: RouterProps<Q> | null;
readyCallbacks: RouterCallback[];
ready(cb: RouterCallback): void;
}
export interface WithRouterProps {
router: SingletonRouter;
export interface WithRouterProps<Q = DefaultQuery> {
router: SingletonRouter<Q>;
}
export function withRouter<T extends {}>(
Component: React.ComponentType<T & WithRouterProps>,
// Manually disabling the no-unnecessary-generics rule so users can
// retain type inference if they warp their component in withRouter
// without defining props explicitly
export function withRouter<T extends {}, Q = DefaultQuery>(
// tslint:disable-next-line:no-unnecessary-generics
Component: React.ComponentType<T & WithRouterProps<Q>>,
): React.ComponentType<T>;
declare const Router: SingletonRouter;
+10
View File
@@ -96,3 +96,13 @@ class TestComponent extends React.Component<TestComponentProps & WithRouterProps
}
withRouter(TestComponent);
interface TestSFCQuery {
test?: string;
}
interface TestSFCProps extends WithRouterProps<TestSFCQuery> { }
const TestSFC: React.SFC<TestSFCProps> = ({ router }) => {
return <div>{router.query && router.query.test}</div>;
};