Merge pull request #25711 from resir014/master

[next] 6.0.0 - Added `next/app` typings, NextContext object, and various typing improvements
This commit is contained in:
Mine Starks
2018-06-13 08:47:38 -07:00
committed by GitHub
7 changed files with 175 additions and 45 deletions

18
types/next/app.d.ts vendored Normal file
View File

@@ -0,0 +1,18 @@
import * as React from "react";
import { NextContext } from ".";
import { SingletonRouter } from "./router";
export interface AppComponentProps {
Component: React.ComponentType<any>;
pageProps: any;
}
export interface AppComponentContext {
Component: React.ComponentType<any>;
router: SingletonRouter;
ctx: NextContext;
}
export class Container extends React.Component {}
export default class App<TProps = {}> extends React.Component<TProps & AppComponentProps> {}

View File

@@ -1,30 +1,5 @@
import * as React from "react";
import * as http from "http";
export interface Context {
err?: Error;
req: http.IncomingMessage;
res: http.ServerResponse;
pathname: string;
query?: {
[key: string]:
| boolean
| boolean[]
| number
| number[]
| string
| string[];
};
asPath: string;
renderPage(
enhancer?: (page: React.Component) => React.ComponentType<any>
): {
html?: string;
head: Array<React.ReactElement<any>>;
errorHtml: string;
};
}
import { NextContext } from ".";
export interface DocumentProps {
__NEXT_DATA__?: any;
@@ -38,9 +13,21 @@ 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<any>
): {
[key: string]: any
};
}
export class Head extends React.Component<any> {}
export class Main extends React.Component {}
export class NextScript extends React.Component {}
export default class extends React.Component<DocumentProps> {
static getInitialProps(ctx: Context): DocumentProps;
static getInitialProps(ctx: NextContext): DocumentProps;
}

63
types/next/index.d.ts vendored
View File

@@ -1,7 +1,9 @@
// Type definitions for next 2.4
// Type definitions for next 6.0
// Project: https://github.com/zeit/next.js
// Definitions by: Drew Hays <https://github.com/dru89>
// Brice BERNARD <https://github.com/brikou>
// James Hegedus <https://github.com/jthegedus>
// Resi Respati <https://github.com/resir014>
// Scott Jones <https://github.com/scottdj92>
// Definitions: https://github.com/DefinitelyTyped/DefinitelyTyped
// TypeScript Version: 2.6
@@ -11,7 +13,44 @@
import * as http from "http";
import * as url from "url";
import { Response as NodeResponse } from "node-fetch";
declare namespace next {
/**
* Context object used in methods like `getInitialProps()`
* <<https://github.com/zeit/next.js/issues/1651>>
*/
interface NextContext {
/** path section of URL */
pathname: string;
/** query string section of URL parsed as an object */
query: {
[key: string]:
| boolean
| boolean[]
| number
| number[]
| string
| string[];
};
/** 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?: NodeResponse;
/** Error object if any error is encountered during the rendering */
err?: Error;
}
type NextSFC<TProps = {}> = NextStatelessComponent<TProps>;
interface NextStatelessComponent<TProps = {}>
extends React.StatelessComponent<TProps> {
getInitialProps?: (ctx: NextContext) => Promise<TProps>;
}
type UrlLike = url.UrlObject | url.Url;
interface ServerConfig {
@@ -41,12 +80,12 @@ declare namespace next {
handleRequest(
req: http.IncomingMessage,
res: http.ServerResponse,
parsedUrl?: UrlLike,
parsedUrl?: UrlLike
): Promise<void>;
getRequestHandler(): (
req: http.IncomingMessage,
res: http.ServerResponse,
parsedUrl?: UrlLike,
parsedUrl?: UrlLike
) => Promise<void>;
prepare(): Promise<void>;
close(): Promise<void>;
@@ -55,7 +94,7 @@ declare namespace next {
run(
req: http.IncomingMessage,
res: http.ServerResponse,
parsedUrl: UrlLike,
parsedUrl: UrlLike
): Promise<void>;
render(
@@ -71,7 +110,7 @@ declare namespace next {
| string
| string[];
},
parsedUrl?: UrlLike,
parsedUrl?: UrlLike
): Promise<void>;
renderError(
err: any,
@@ -86,12 +125,12 @@ declare namespace next {
| number[]
| string
| string[];
},
}
): Promise<void>;
render404(
req: http.IncomingMessage,
res: http.ServerResponse,
parsedUrl: UrlLike,
parsedUrl: UrlLike
): Promise<void>;
renderToHTML(
req: http.IncomingMessage,
@@ -105,7 +144,7 @@ declare namespace next {
| number[]
| string
| string[];
},
}
): Promise<string>;
renderErrorToHTML(
err: any,
@@ -120,13 +159,13 @@ declare namespace next {
| number[]
| string
| string[];
},
}
): Promise<string>;
serveStatic(
req: http.IncomingMessage,
res: http.ServerResponse,
path: string,
path: string
): Promise<void>;
isServeableUrl(path: string): boolean;
isInternalUrl(req: http.IncomingMessage): boolean;
@@ -135,12 +174,12 @@ declare namespace next {
getCompilationError(
page: string,
req: http.IncomingMessage,
res: http.ServerResponse,
res: http.ServerResponse
): Promise<any>;
handleBuildHash(
filename: string,
hash: string,
res: http.ServerResponse,
res: http.ServerResponse
): void;
send404(res: http.ServerResponse): void;
}

View File

@@ -0,0 +1,27 @@
import * as React from "react";
import App, { Container } from "next/app";
interface NextComponentProps {
example: string;
}
class TestApp extends App<NextComponentProps> {
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 (
<Container>
<Component {...pageProps} />
</Container>
);
}
}

View File

@@ -0,0 +1,28 @@
import * as React from "react";
import { NextStatelessComponent, NextContext } from "next";
interface NextComponentProps {
example: string;
}
class ClassNext extends React.Component<NextComponentProps> {
static async getInitialProps(ctx: NextContext) {
const { example } = ctx.query;
return { example };
}
render() {
return (
<div>I'm a class component! {this.props.example}</div>
);
}
}
const StatelessNext: NextStatelessComponent<NextComponentProps> = ({ example }) => (
<div>I'm a stateless component! {example}</div>
);
StatelessNext.getInitialProps = async ({ query }: NextContext) => {
const { example } = query;
return { example: example as string };
};

View File

@@ -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 = (
<Document any="property" should="work" here>
<document.Head some="more" properties>
<Head some="more" properties>
<meta name="description" content="Head can have children, too!" />
</document.Head>
<document.Main />
<document.NextScript />
</Head>
<Main />
<NextScript />
</Document>
);
const Wrapper: React.SFC = ({ children }) => <React.Fragment>{children}</React.Fragment>;
export default class MyDocument extends Document {
static async getInitialProps({ renderPage }: NextDocumentContext) {
// Without callback
const page = renderPage();
// With callback
const differentPage = renderPage(App => props => <Wrapper><App {...props} /></Wrapper>);
const style = {};
return { ...page, style };
}
render() {
return (
<html>
<Head>
<title>My page</title>
<style id='cxs-style' dangerouslySetInnerHTML={{ __html: this.props.style }} />
</Head>
<body>
<Main />
<NextScript />
</body>
</html>
);
}
}

View File

@@ -20,6 +20,7 @@
},
"files": [
"index.d.ts",
"app.d.ts",
"document.d.ts",
"dynamic.d.ts",
"error.d.ts",
@@ -28,11 +29,13 @@
"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",
"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"
]
}