fix(types/next): Add req and res NextContext typedefs used in next export (#36591)

* fix(types/next): Add req and res NextContext typedefs used in `next export`

On `next export` command, `req` and `res` objects are hardcoded simple objects: https://github.com/zeit/next.js/blob/master/packages/next/export/worker.js#L42-L43 and thus they have different type definition (i.e. `res.writeHead` is missing which might cause [such code](https://github.com/zeit/next.js/wiki/Redirecting-in-%60getInitialProps%60) to blow up with a `TypeError: res.writeHead is not a function` .

* fixup! fix(types/next): Add req and res NextContext typedefs used in `next export`
This commit is contained in:
Jack Tomaszewski
2019-07-09 16:31:50 -07:00
committed by Armando Aguirre
parent 9bbed9600f
commit e15f8a4f68
2 changed files with 43 additions and 9 deletions
+38 -4
View File
@@ -31,6 +31,34 @@ declare namespace next {
type ServerConfig = NextConfig;
// End Deprecated
/**
* HTTP request object (server only, non-export mode)
*/
type NextReq<CustomReq = {}> = http.IncomingMessage & CustomReq;
/**
* HTTP request object (server only, `next export` mode)
*
* Note: We're using `Partial` here (instead of `{ url?: string }`)
* in order to avoid TS raising typedef errors
* when using it like `req && req.getHeaderNames ? req.getHeaderNames() : []`.
*/
type NextExportReq<CustomReq = {}> = Partial<NextReq<CustomReq>>;
/**
* HTTP response object (server only, non-export mode)
*/
type NextResponse = http.ServerResponse;
/**
* HTTP response object (server only, `next export` mode)
*
* Note: We're using `Partial` here (instead of `{}`)
* in order to avoid TS raising typedef errors
* when using it like `res && res.getHeaderNames ? res.getHeaderNames() : []`.
*/
type NextExportResponse = Partial<NextResponse>;
/**
* Context object used in methods like `getInitialProps()`
* https://github.com/zeit/next.js/blob/7.0.0/server/render.js#L97
@@ -48,10 +76,16 @@ declare namespace next {
query: Q;
/** String of the actual path (including the query) shows in the browser */
asPath: string;
/** HTTP request object (server only) */
req?: http.IncomingMessage & CustomReq;
/** HTTP response object (server only) */
res?: http.ServerResponse;
/**
* HTTP request object (server only)
* Note: In `next export` mode, this will consist of only `{ url?: string }`.
*/
req?: NextReq<CustomReq> | NextExportReq<CustomReq>;
/**
* HTTP response object (server only)
* Note: In `next export` mode, this will be empty `{}` object.
*/
res?: NextResponse | NextExportResponse;
/** Fetch Response object (client only) - from https://developer.mozilla.org/en-US/docs/Web/API/Response */
jsonPageRes?: NodeResponse;
/** Error object if any error is encountered during the rendering */
+5 -5
View File
@@ -134,13 +134,12 @@ const explicitTypesRenderResponseTwo = renderPage<PageInitialProps, ProcessedIni
App => ({ foo, bar }) => <App fooLength={foo.length} bar={!!bar} />
);
class MyDocumentWithCustomContext extends Document<{ example: string }> {
static async getInitialProps(
ctx: NextDocumentContext<DefaultQuery, { customField: "custom value" }>
) {
class MyDocumentWithCustomContext extends Document<{ example: string; url: string }> {
static async getInitialProps(ctx: NextDocumentContext<DefaultQuery, { customField: 'custom value' }>) {
const initialProps = await Document.getInitialProps(ctx);
const example = ctx.req ? ctx.req.customField : undefined;
return { ...initialProps, example };
const url = ctx.req ? ctx.req.url : undefined;
return { ...initialProps, example, url };
}
render() {
@@ -151,6 +150,7 @@ class MyDocumentWithCustomContext extends Document<{ example: string }> {
</Head>
<body className="custom_class">
<h1>{this.props.example}</h1>
<h2>{this.props.url}</h2>
<Main />
<NextScript />
</body>