diff --git a/types/next/app.d.ts b/types/next/app.d.ts index e086af0ca8..d077c0e95a 100644 --- a/types/next/app.d.ts +++ b/types/next/app.d.ts @@ -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 { Component: React.ComponentType; - router: RouterProps; + router: RouterProps; pageProps: any; } -export interface AppComponentContext { +export interface AppComponentContext { Component: React.ComponentType; - router: RouterProps; - ctx: NextContext; + router: RouterProps; + ctx: NextContext; } -export class Container extends React.Component {} +export class Container extends React.Component { } -export default class App extends React.Component {} +export default class App extends React.Component> { } diff --git a/types/next/index.d.ts b/types/next/index.d.ts index 2d87121d61..71d769ed31 100644 --- a/types/next/index.d.ts +++ b/types/next/index.d.ts @@ -24,11 +24,11 @@ declare namespace next { * Context object used in methods like `getInitialProps()` * <> */ - interface NextContext { + interface NextContext { /** 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 = NextStatelessComponent; - interface NextStatelessComponent + type NextSFC = NextStatelessComponent; + interface NextStatelessComponent extends React.StatelessComponent { - getInitialProps?: (ctx: NextContext) => Promise; + getInitialProps?: (ctx: NextContext) => Promise; } type UrlLike = url.UrlObject | url.Url; diff --git a/types/next/router.d.ts b/types/next/router.d.ts index fe3563d473..be3665e3d5 100644 --- a/types/next/router.d.ts +++ b/types/next/router.d.ts @@ -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 { // 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 extends RouterProps { + router: RouterProps | null; readyCallbacks: RouterCallback[]; ready(cb: RouterCallback): void; } -export interface WithRouterProps { - router: SingletonRouter; +export interface WithRouterProps { + router: SingletonRouter; } -export function withRouter( - Component: React.ComponentType, +// 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( + // tslint:disable-next-line:no-unnecessary-generics + Component: React.ComponentType>, ): React.ComponentType; declare const Router: SingletonRouter; diff --git a/types/next/test/next-router-tests.tsx b/types/next/test/next-router-tests.tsx index fdcf1de3ff..04fa50b912 100644 --- a/types/next/test/next-router-tests.tsx +++ b/types/next/test/next-router-tests.tsx @@ -96,3 +96,13 @@ class TestComponent extends React.Component { } + +const TestSFC: React.SFC = ({ router }) => { + return
{router.query && router.query.test}
; +};