From bd2218b6f6f1449636dbd32a5458c65be4ccb54b Mon Sep 17 00:00:00 2001 From: James Hegedus Date: Mon, 12 Mar 2018 20:30:25 +1100 Subject: [PATCH 01/20] [WIP] Next.js Context Object type --- types/next/index.d.ts | 12 ++++++++++++ 1 file changed, 12 insertions(+) diff --git a/types/next/index.d.ts b/types/next/index.d.ts index 036e9f58ce..3ebcb9b395 100644 --- a/types/next/index.d.ts +++ b/types/next/index.d.ts @@ -6,11 +6,23 @@ // TypeScript Version: 2.6 /// +/// import * as http from "http"; import * as url from "url"; +import * as fetch from "isomorphic-unfetch"; declare namespace next { + interface NextContext { + pathname?: string; //path section of URL + query?: any; // meant to be an object - // query string section of URL parsed as an object + asPath?: string; // String of the actual path (including the query) shows in the browser + req?: http.IncomingMessage; //HTTP request object (server only) + res?: http.ServerResponse; //HTTP response object (server only) + jsonPageRes?: fetch.IsomorphicResponse; //Fetch Response object (client only) - from https://developer.mozilla.org/en-US/docs/Web/API/Response + err?: Error; //Error object if any error is encountered during the rendering + } + type UrlLike = url.UrlObject | url.Url; interface ServerConfig { From bcf98ec1f542feb91866a95818824960ec0c796f Mon Sep 17 00:00:00 2001 From: James Hegedus Date: Mon, 12 Mar 2018 20:38:23 +1100 Subject: [PATCH 02/20] add self to receive update notifications --- types/next/index.d.ts | 1 + 1 file changed, 1 insertion(+) diff --git a/types/next/index.d.ts b/types/next/index.d.ts index 3ebcb9b395..a6cf91ddc6 100644 --- a/types/next/index.d.ts +++ b/types/next/index.d.ts @@ -2,6 +2,7 @@ // Project: https://github.com/zeit/next.js // Definitions by: Drew Hays // Brice BERNARD +// James Hegedus // Definitions: https://github.com/DefinitelyTyped/DefinitelyTyped // TypeScript Version: 2.6 From 4b0b64bd58aa00102f3f081a84fcc695378257c8 Mon Sep 17 00:00:00 2001 From: James Hegedus Date: Mon, 12 Mar 2018 20:43:21 +1100 Subject: [PATCH 03/20] fix some lint errors and answer qs from PR template --- types/next/index.d.ts | 14 +++++++------- 1 file changed, 7 insertions(+), 7 deletions(-) diff --git a/types/next/index.d.ts b/types/next/index.d.ts index a6cf91ddc6..77cea7062d 100644 --- a/types/next/index.d.ts +++ b/types/next/index.d.ts @@ -1,4 +1,4 @@ -// Type definitions for next 2.4 +// Type definitions for next 5.0 // Project: https://github.com/zeit/next.js // Definitions by: Drew Hays // Brice BERNARD @@ -7,21 +7,21 @@ // TypeScript Version: 2.6 /// -/// import * as http from "http"; import * as url from "url"; import * as fetch from "isomorphic-unfetch"; declare namespace next { + // <> interface NextContext { - pathname?: string; //path section of URL + pathname?: string; // path section of URL query?: any; // meant to be an object - // query string section of URL parsed as an object asPath?: string; // String of the actual path (including the query) shows in the browser - req?: http.IncomingMessage; //HTTP request object (server only) - res?: http.ServerResponse; //HTTP response object (server only) - jsonPageRes?: fetch.IsomorphicResponse; //Fetch Response object (client only) - from https://developer.mozilla.org/en-US/docs/Web/API/Response - err?: Error; //Error object if any error is encountered during the rendering + req?: http.IncomingMessage; // HTTP request object (server only) + res?: http.ServerResponse; // HTTP response object (server only) + jsonPageRes?: fetch.IsomorphicResponse; // Fetch Response object (client only) - from https://developer.mozilla.org/en-US/docs/Web/API/Response + err?: Error; // Error object if any error is encountered during the rendering } type UrlLike = url.UrlObject | url.Url; From 16fe1426ca2d73ae73299e0e6a9f76c3075a65ad Mon Sep 17 00:00:00 2001 From: Resi Respati Date: Wed, 2 May 2018 00:29:28 +0700 Subject: [PATCH 04/20] [next] NextContext type adjustments * Add renderPage property to `NextContext` * `pathname`, `query`, and `asPath` is always defined * fixed object types, add proper JSDoc to context interface --- types/next/index.d.ts | 29 ++++++++++++++++++++++------- 1 file changed, 22 insertions(+), 7 deletions(-) diff --git a/types/next/index.d.ts b/types/next/index.d.ts index 77cea7062d..5ecfba20da 100644 --- a/types/next/index.d.ts +++ b/types/next/index.d.ts @@ -15,13 +15,28 @@ import * as fetch from "isomorphic-unfetch"; declare namespace next { // <> interface NextContext { - pathname?: string; // path section of URL - query?: any; // meant to be an object - // query string section of URL parsed as an object - asPath?: string; // String of the actual path (including the query) shows in the browser - req?: http.IncomingMessage; // HTTP request object (server only) - res?: http.ServerResponse; // HTTP response object (server only) - jsonPageRes?: fetch.IsomorphicResponse; // Fetch Response object (client only) - from https://developer.mozilla.org/en-US/docs/Web/API/Response - err?: Error; // Error object if any error is encountered during the rendering + /** path section of URL */ + pathname: string + /** query string section of URL parsed as an object */ + query: { + [key: string]: any + } + /** String of the actual path (including the query) shows in the browser */ + asPath: string + /** HTTP request object (server only) */ + req?: http.IncomingMessage + /** HTTP response object (server only) */ + res?: http.ServerResponse + /** Fetch Response object (client only) - from https://developer.mozilla.org/en-US/docs/Web/API/Response */ + jsonPageRes?: fetch.IsomorphicResponse + /** Error object if any error is encountered during the rendering */ + err?: Error + /** a callback that executes the actual React rendering logic (synchronously) */ + renderPage( + cb: (enhancer: () => JSX.Element) => React.ComponentType + ): { + [key: string]: any + } } type UrlLike = url.UrlObject | url.Url; From 6145af0a3acff432e4d24a5e90ec6125bce7f5b6 Mon Sep 17 00:00:00 2001 From: Resi Respati Date: Wed, 2 May 2018 00:34:12 +0700 Subject: [PATCH 05/20] [next] renderPage callback should be optional --- types/next/index.d.ts | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/types/next/index.d.ts b/types/next/index.d.ts index 5ecfba20da..7f7c58140e 100644 --- a/types/next/index.d.ts +++ b/types/next/index.d.ts @@ -33,7 +33,7 @@ declare namespace next { err?: Error /** a callback that executes the actual React rendering logic (synchronously) */ renderPage( - cb: (enhancer: () => JSX.Element) => React.ComponentType + cb?: (enhancer: () => JSX.Element) => React.ComponentType ): { [key: string]: any } From 07de2cfd39a8da31d5013d77180ed45a72637ff1 Mon Sep 17 00:00:00 2001 From: Resi Respati Date: Sat, 5 May 2018 00:34:47 +0700 Subject: [PATCH 06/20] [next] target next@6.0.0 `next@6.0.0` is out, so let's change the target version to it --- types/next/index.d.ts | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/types/next/index.d.ts b/types/next/index.d.ts index 7f7c58140e..3abb22a2a4 100644 --- a/types/next/index.d.ts +++ b/types/next/index.d.ts @@ -1,4 +1,4 @@ -// Type definitions for next 5.0 +// Type definitions for next 6.0 // Project: https://github.com/zeit/next.js // Definitions by: Drew Hays // Brice BERNARD From a47662329cfbdd2978f58a4591248069341c48df Mon Sep 17 00:00:00 2001 From: Resi Respati Date: Fri, 11 May 2018 22:38:21 +0700 Subject: [PATCH 07/20] Add NextStatelessComponent interface --- types/next/index.d.ts | 6 ++++++ types/next/test/next-component-tests.tsx | 26 ++++++++++++++++++++++++ types/next/tsconfig.json | 3 ++- 3 files changed, 34 insertions(+), 1 deletion(-) create mode 100644 types/next/test/next-component-tests.tsx diff --git a/types/next/index.d.ts b/types/next/index.d.ts index 3abb22a2a4..52c34542ba 100644 --- a/types/next/index.d.ts +++ b/types/next/index.d.ts @@ -3,6 +3,7 @@ // Definitions by: Drew Hays // Brice BERNARD // James Hegedus +// Resi Respati // Definitions: https://github.com/DefinitelyTyped/DefinitelyTyped // TypeScript Version: 2.6 @@ -39,6 +40,11 @@ declare namespace next { } } + type NextSFC

= NextStatelessComponent

; + interface NextStatelessComponent

extends React.StatelessComponent

{ + getInitialProps?: (ctx: NextContext) => Promise; + } + type UrlLike = url.UrlObject | url.Url; interface ServerConfig { diff --git a/types/next/test/next-component-tests.tsx b/types/next/test/next-component-tests.tsx new file mode 100644 index 0000000000..33ecb6bc93 --- /dev/null +++ b/types/next/test/next-component-tests.tsx @@ -0,0 +1,26 @@ +import * as React from "react"; +import { NextStatelessComponent } from "next"; + +interface NextComponentProps { + example: string +} + +class ClassNext extends React.Component { + async getInitialProps() { + return { example: 'example' } + } + + render() { + return ( +

I'm a stateless component! {this.props.example}
+ ) + } +} + +const StatelessNext: NextStatelessComponent = ({ example }) => ( +
I'm a stateless component! {example}
+) + +StatelessNext.getInitialProps = async () => { + return { example: 'example' } +} diff --git a/types/next/tsconfig.json b/types/next/tsconfig.json index 48d3f0c8be..d22768e4a1 100644 --- a/types/next/tsconfig.json +++ b/types/next/tsconfig.json @@ -33,6 +33,7 @@ "test/next-document-tests.tsx", "test/next-link-tests.tsx", "test/next-dynamic-tests.tsx", - "test/next-router-tests.tsx" + "test/next-router-tests.tsx", + "test/next-component-tests.tsx" ] } From ba8d541851f904fba222022c449683fe5c3d6cff Mon Sep 17 00:00:00 2001 From: Resi Respati Date: Fri, 11 May 2018 22:42:03 +0700 Subject: [PATCH 08/20] [next] Use NodeResponse because of unfetch.IsomorphicResponse --- types/next/index.d.ts | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) diff --git a/types/next/index.d.ts b/types/next/index.d.ts index 52c34542ba..d83b787b4a 100644 --- a/types/next/index.d.ts +++ b/types/next/index.d.ts @@ -11,7 +11,8 @@ import * as http from "http"; import * as url from "url"; -import * as fetch from "isomorphic-unfetch"; + +import { Response as NodeResponse } from "node-fetch"; declare namespace next { // <> @@ -29,7 +30,7 @@ declare namespace next { /** HTTP response object (server only) */ res?: http.ServerResponse /** Fetch Response object (client only) - from https://developer.mozilla.org/en-US/docs/Web/API/Response */ - jsonPageRes?: fetch.IsomorphicResponse + jsonPageRes?: NodeResponse /** Error object if any error is encountered during the rendering */ err?: Error /** a callback that executes the actual React rendering logic (synchronously) */ From 4dff7d985840fbe92101a8d5d3d8b5ccca9eb5f8 Mon Sep 17 00:00:00 2001 From: Resi Respati Date: Fri, 11 May 2018 22:51:14 +0700 Subject: [PATCH 09/20] [next] Added typings for `next/app` --- types/next/app.d.ts | 10 ++++++++++ types/next/test/next-app-tests.tsx | 27 +++++++++++++++++++++++++++ types/next/tsconfig.json | 1 + 3 files changed, 38 insertions(+) create mode 100644 types/next/app.d.ts create mode 100644 types/next/test/next-app-tests.tsx diff --git a/types/next/app.d.ts b/types/next/app.d.ts new file mode 100644 index 0000000000..6d10d77af8 --- /dev/null +++ b/types/next/app.d.ts @@ -0,0 +1,10 @@ +import * as React from "react"; + +export interface AppComponentProps { + Component: React.ComponentType; + pageProps: any +} + +export class Container extends React.Component {} + +export default class App

extends React.Component

{} diff --git a/types/next/test/next-app-tests.tsx b/types/next/test/next-app-tests.tsx new file mode 100644 index 0000000000..3e7c56f87c --- /dev/null +++ b/types/next/test/next-app-tests.tsx @@ -0,0 +1,27 @@ +import * as React from "react"; +import App, { Container } from "next/app"; + +interface NextComponentProps { + example: string; +} + +class TestApp extends App { + static async getInitialProps({ Component, router, ctx }: any) { + let pageProps = {}; + + if (Component.getInitialProps) { + pageProps = await Component.getInitialProps(ctx); + } + + return { pageProps }; + } + + render() { + const { Component, pageProps } = this.props; + return ( + + + + ); + } +} diff --git a/types/next/tsconfig.json b/types/next/tsconfig.json index d22768e4a1..36aef39491 100644 --- a/types/next/tsconfig.json +++ b/types/next/tsconfig.json @@ -28,6 +28,7 @@ "router.d.ts", "config.d.ts", "test/next-tests.ts", + "test/next-app-tests.tsx", "test/next-error-tests.tsx", "test/next-head-tests.tsx", "test/next-document-tests.tsx", From 3c4579913defe15ac6bd51858f88dc17e7477d3f Mon Sep 17 00:00:00 2001 From: Resi Respati Date: Fri, 11 May 2018 23:03:41 +0700 Subject: [PATCH 10/20] [next] run dtslint --- types/next/index.d.ts | 21 ++++++++++++--------- types/next/test/next-component-tests.tsx | 12 ++++++------ 2 files changed, 18 insertions(+), 15 deletions(-) diff --git a/types/next/index.d.ts b/types/next/index.d.ts index d83b787b4a..939dc27bdb 100644 --- a/types/next/index.d.ts +++ b/types/next/index.d.ts @@ -15,30 +15,33 @@ import * as url from "url"; import { Response as NodeResponse } from "node-fetch"; declare namespace next { - // <> + /** + * Context object used in methods like `getInitialProps()` + * <> + */ interface NextContext { /** path section of URL */ - pathname: string + pathname: string; /** query string section of URL parsed as an object */ query: { [key: string]: any - } + }; /** String of the actual path (including the query) shows in the browser */ - asPath: string + asPath: string; /** HTTP request object (server only) */ - req?: http.IncomingMessage + req?: http.IncomingMessage; /** HTTP response object (server only) */ - res?: http.ServerResponse + res?: http.ServerResponse; /** Fetch Response object (client only) - from https://developer.mozilla.org/en-US/docs/Web/API/Response */ - jsonPageRes?: NodeResponse + jsonPageRes?: NodeResponse; /** Error object if any error is encountered during the rendering */ - err?: Error + err?: Error; /** a callback that executes the actual React rendering logic (synchronously) */ renderPage( cb?: (enhancer: () => JSX.Element) => React.ComponentType ): { [key: string]: any - } + }; } type NextSFC

= NextStatelessComponent

; diff --git a/types/next/test/next-component-tests.tsx b/types/next/test/next-component-tests.tsx index 33ecb6bc93..a6e870f8e2 100644 --- a/types/next/test/next-component-tests.tsx +++ b/types/next/test/next-component-tests.tsx @@ -2,25 +2,25 @@ import * as React from "react"; import { NextStatelessComponent } from "next"; interface NextComponentProps { - example: string + example: string; } class ClassNext extends React.Component { async getInitialProps() { - return { example: 'example' } + return { example: 'example' }; } render() { return (

I'm a stateless component! {this.props.example}
- ) + ); } } const StatelessNext: NextStatelessComponent = ({ example }) => (
I'm a stateless component! {example}
-) +); StatelessNext.getInitialProps = async () => { - return { example: 'example' } -} + return { example: 'example' }; +}; From 3c5384acca044e06c4e214cf5b113b139a95cb7c Mon Sep 17 00:00:00 2001 From: Resi Respati Date: Fri, 11 May 2018 23:12:07 +0700 Subject: [PATCH 11/20] [next] Added AppComponentContext type --- types/next/app.d.ts | 7 +++++++ 1 file changed, 7 insertions(+) diff --git a/types/next/app.d.ts b/types/next/app.d.ts index 6d10d77af8..512c5f996f 100644 --- a/types/next/app.d.ts +++ b/types/next/app.d.ts @@ -1,10 +1,17 @@ import * as React from "react"; +import { NextContext } from "next"; export interface AppComponentProps { Component: React.ComponentType; pageProps: any } +export interface AppComponentContext { + Component: any; + router: any; // TODO: could be SingletonRouter? + ctx: NextContext; +} + export class Container extends React.Component {} export default class App

extends React.Component

{} From f3d3de950904a3e46137c31a222e1b2d4b4d4841 Mon Sep 17 00:00:00 2001 From: Resi Respati Date: Fri, 11 May 2018 23:16:42 +0700 Subject: [PATCH 12/20] [next] include app.d.ts in bundle --- types/next/tsconfig.json | 1 + 1 file changed, 1 insertion(+) diff --git a/types/next/tsconfig.json b/types/next/tsconfig.json index 36aef39491..125953fcd6 100644 --- a/types/next/tsconfig.json +++ b/types/next/tsconfig.json @@ -20,6 +20,7 @@ }, "files": [ "index.d.ts", + "app.d.ts", "document.d.ts", "dynamic.d.ts", "error.d.ts", From 92db478980b2221b31f995a0658191902ba9bb4f Mon Sep 17 00:00:00 2001 From: Resi Respati Date: Fri, 11 May 2018 23:17:40 +0700 Subject: [PATCH 13/20] [next] re-run dtslint --- types/next/app.d.ts | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/types/next/app.d.ts b/types/next/app.d.ts index 512c5f996f..0296440ddb 100644 --- a/types/next/app.d.ts +++ b/types/next/app.d.ts @@ -1,9 +1,9 @@ import * as React from "react"; -import { NextContext } from "next"; +import { NextContext } from "."; export interface AppComponentProps { Component: React.ComponentType; - pageProps: any + pageProps: any; } export interface AppComponentContext { From 28b1367d70342534ff1bcd2ecedcc27b0da2f6d5 Mon Sep 17 00:00:00 2001 From: Resi Respati Date: Sat, 12 May 2018 11:51:42 +0700 Subject: [PATCH 14/20] [next] fix tests (getInitialProps should be static) --- types/next/test/next-component-tests.tsx | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/types/next/test/next-component-tests.tsx b/types/next/test/next-component-tests.tsx index a6e870f8e2..fefde092ea 100644 --- a/types/next/test/next-component-tests.tsx +++ b/types/next/test/next-component-tests.tsx @@ -6,7 +6,7 @@ interface NextComponentProps { } class ClassNext extends React.Component { - async getInitialProps() { + static async getInitialProps() { return { example: 'example' }; } From 9d68e22a0c62fbd58869ab901ad09badf8eb6dcf Mon Sep 17 00:00:00 2001 From: Resi Respati Date: Wed, 16 May 2018 21:57:28 +0700 Subject: [PATCH 15/20] [next] separate context objects for Document + fix tests --- types/next/document.d.ts | 13 +++++++++ types/next/index.d.ts | 6 ---- types/next/test/next-document-tests.tsx | 38 +++++++++++++++++++++---- 3 files changed, 46 insertions(+), 11 deletions(-) diff --git a/types/next/document.d.ts b/types/next/document.d.ts index 4696819626..01344de7c8 100644 --- a/types/next/document.d.ts +++ b/types/next/document.d.ts @@ -1,4 +1,5 @@ import * as React from "react"; +import { NextContext } from "."; export interface DocumentProps { __NEXT_DATA__?: any; @@ -9,6 +10,18 @@ export interface DocumentProps { [key: string]: any; } +/** + * Context object used inside `Document` + */ +export interface NextDocumentContext extends NextContext { + /** A callback that executes the actual React rendering logic (synchronously) */ + renderPage( + cb?: (enhancer: () => JSX.Element) => React.ComponentType + ): { + [key: string]: any + }; +} + export class Head extends React.Component {} export class Main extends React.Component {} export class NextScript extends React.Component {} diff --git a/types/next/index.d.ts b/types/next/index.d.ts index 939dc27bdb..6679420ba3 100644 --- a/types/next/index.d.ts +++ b/types/next/index.d.ts @@ -36,12 +36,6 @@ declare namespace next { jsonPageRes?: NodeResponse; /** Error object if any error is encountered during the rendering */ err?: Error; - /** a callback that executes the actual React rendering logic (synchronously) */ - renderPage( - cb?: (enhancer: () => JSX.Element) => React.ComponentType - ): { - [key: string]: any - }; } type NextSFC

= NextStatelessComponent

; diff --git a/types/next/test/next-document-tests.tsx b/types/next/test/next-document-tests.tsx index 0177d1d451..2b3257cd25 100644 --- a/types/next/test/next-document-tests.tsx +++ b/types/next/test/next-document-tests.tsx @@ -1,12 +1,40 @@ -import Document, * as document from "next/document"; +import Document, { Head, Main, NextScript, NextDocumentContext } from 'next/document'; import * as React from "react"; const results = ( - + - - - + +

+ ); + +const Wrapper: React.SFC = ({ children }) => {children}; + +export default class MyDocument extends Document { + static async getInitialProps({ renderPage }: NextDocumentContext) { + // Without callback + const page = renderPage(); + // With callback + const differentPage = renderPage(App => props => ); + const style = {}; + return { ...page, style }; + } + + render() { + return ( + + + My page +