diff --git a/types/next/index.d.ts b/types/next/index.d.ts index 399963cbd8..08e82106ab 100644 --- a/types/next/index.d.ts +++ b/types/next/index.d.ts @@ -16,18 +16,18 @@ import * as url from "url"; import { Response as NodeResponse } from "node-fetch"; -import { SingletonRouter } from './router'; +import { SingletonRouter, DefaultQuery } from './router'; declare namespace next { - /** Map object used in query strings. */ - type QueryStringMapObject = Record; + // Deprecated + type QueryStringMapObject = DefaultQuery; /** * Context object used in methods like `getInitialProps()` * https://github.com/zeit/next.js/blob/6.1.1/server/render.js#L77 * https://github.com/zeit/next.js/blob/6.1.1/readme.md#fetching-data-and-component-lifecycle */ - interface NextContext { + interface NextContext { /** path section of URL */ pathname: string; /** query string section of URL parsed as an object */ @@ -44,8 +44,8 @@ declare namespace next { err?: Error; } - type NextSFC = NextStatelessComponent; - interface NextStatelessComponent + type NextSFC = NextStatelessComponent; + interface NextStatelessComponent extends React.StatelessComponent { getInitialProps?: (ctx: NextContext) => Promise; } @@ -142,28 +142,28 @@ declare namespace next { req: http.IncomingMessage, res: http.ServerResponse, pathname: string, - query?: QueryStringMapObject, + query?: DefaultQuery, parsedUrl?: UrlLike ): Promise; renderToHTML( req: http.IncomingMessage, res: http.ServerResponse, pathname: string, - query?: QueryStringMapObject + query?: DefaultQuery ): Promise; renderError( err: any, req: http.IncomingMessage, res: http.ServerResponse, pathname: string, - query?: QueryStringMapObject + query?: DefaultQuery ): Promise; renderErrorToHTML( err: any, req: http.IncomingMessage, res: http.ServerResponse, pathname: string, - query?: QueryStringMapObject + query?: DefaultQuery ): Promise; render404( req: http.IncomingMessage, diff --git a/types/next/router.d.ts b/types/next/router.d.ts index be3665e3d5..2039b213f8 100644 --- a/types/next/router.d.ts +++ b/types/next/router.d.ts @@ -26,15 +26,7 @@ export type PopStateCallback = (state: any) => boolean | undefined; export type RouterCallback = () => void; -export interface DefaultQuery { - [key: string]: - | boolean - | boolean[] - | number - | number[] - | string - | string[]; -} +export type DefaultQuery = Record; export interface RouterProps { // url property fields diff --git a/types/next/test/next-app-tests.tsx b/types/next/test/next-app-tests.tsx index 14ef737a06..ffdcbaaf65 100644 --- a/types/next/test/next-app-tests.tsx +++ b/types/next/test/next-app-tests.tsx @@ -1,16 +1,19 @@ import * as React from "react"; -import App, { Container } from "next/app"; +import App, { Container, AppComponentContext } from "next/app"; +import { NextStatelessComponent } from "next"; interface NextComponentProps { example: string; } class TestApp extends App { - static async getInitialProps({ Component, router, ctx }: any) { + static async getInitialProps({ Component, router, ctx }: AppComponentContext) { let pageProps = {}; + // TODO: fix AppComponentContext to return NextComponentType instead of React.ComponentType + const Page = Component as NextStatelessComponent; - if (Component.getInitialProps) { - pageProps = await Component.getInitialProps(ctx); + if (Page.getInitialProps) { + pageProps = await Page.getInitialProps(ctx); } return { pageProps }; diff --git a/types/next/test/next-component-tests.tsx b/types/next/test/next-component-tests.tsx index 55173fd25c..37cd7264ef 100644 --- a/types/next/test/next-component-tests.tsx +++ b/types/next/test/next-component-tests.tsx @@ -5,6 +5,10 @@ interface NextComponentProps { example: string; } +interface TypedQuery { + id?: string; +} + class ClassNext extends React.Component { static async getInitialProps(ctx: NextContext) { const { example } = ctx.query; @@ -18,6 +22,14 @@ class ClassNext extends React.Component { } } +class ClassNextWithTypedQuery extends React.Component { + static async getInitialProps(ctx: NextContext) { + const { id } = ctx.query; + const processQuery = (id?: string) => id; + processQuery(id); + } +} + const StatelessNext: NextStatelessComponent = ({ example }) => (
I'm a stateless component! {example}
);