mirror of
https://github.com/zhigang1992/DefinitelyTyped.git
synced 2026-04-21 21:31:12 +08:00
Update dynamic types and tests.
This commit is contained in:
67
types/next/dynamic.d.ts
vendored
67
types/next/dynamic.d.ts
vendored
@@ -1,29 +1,48 @@
|
||||
import * as React from "react";
|
||||
import {
|
||||
LoadableComponent,
|
||||
CommonOptions as LoadableOptions,
|
||||
LoadingComponentProps as LoadableLoadingComponentProps
|
||||
} from "react-loadable";
|
||||
|
||||
export interface DynamicOptions<TCProps, TLProps> {
|
||||
loading?: React.ComponentType<TLProps>;
|
||||
type Omit<T, K> = Pick<T, Exclude<keyof T, K>>;
|
||||
|
||||
type AsyncComponent<P> = Promise<React.ComponentType<P>>;
|
||||
type AsyncComponentLoader<P> = () => AsyncComponent<P>;
|
||||
|
||||
interface ModuleMapping {
|
||||
[moduleName: string]: AsyncComponent<any>;
|
||||
}
|
||||
|
||||
interface LoadedModuleMapping {
|
||||
[moduleName: string]: React.ComponentType<any>;
|
||||
}
|
||||
|
||||
interface NextDynamicOptions<P = {}> extends Omit<LoadableOptions, "loading" | "modules"> {
|
||||
modules?: () => ModuleMapping; // overridden
|
||||
loading?: LoadableOptions["loading"]; // optional
|
||||
loader?: AsyncComponentLoader<P>; // optional, overriden
|
||||
render?: (props: P, loaded: LoadedModuleMapping) => React.ReactNode; // optional, overriden
|
||||
ssr?: boolean;
|
||||
modules?(
|
||||
props: TCProps & TLProps,
|
||||
): { [key: string]: Promise<React.ComponentType<any>> };
|
||||
render?(
|
||||
props: TCProps & TLProps,
|
||||
modules: { [key: string]: React.ComponentType<any> },
|
||||
): void;
|
||||
loadableGenerated?: {
|
||||
webpack?: any;
|
||||
modules?: any;
|
||||
};
|
||||
}
|
||||
|
||||
export class SameLoopPromise<T> extends Promise<T> {
|
||||
constructor(
|
||||
executor: (
|
||||
resolve: (value?: T) => void,
|
||||
reject: (reason?: any) => void,
|
||||
) => void,
|
||||
);
|
||||
setResult(value: T): void;
|
||||
setError(value: any): void;
|
||||
runIfNeeded(): void;
|
||||
}
|
||||
export default function<TCProps, TLProps>(
|
||||
componentPromise: Promise<React.ComponentType<TCProps>>,
|
||||
options?: DynamicOptions<TCProps, TLProps>,
|
||||
): React.ComponentType<TCProps & TLProps>;
|
||||
type DynamicComponent<P> = React.ComponentType<P> & LoadableComponent;
|
||||
|
||||
/**
|
||||
* Overloaded dynamic function.
|
||||
* https://github.com/zeit/next.js/blob/7.0.0/lib/dynamic.js#L55
|
||||
*/
|
||||
declare function dynamic<P = {}>(
|
||||
options: AsyncComponent<P> | NextDynamicOptions<P>
|
||||
): DynamicComponent<P>;
|
||||
declare function dynamic<P = {}>(
|
||||
asyncModule: AsyncComponent<P>,
|
||||
options: NextDynamicOptions<P>
|
||||
): DynamicComponent<P>;
|
||||
|
||||
export type LoadingComponentProps = LoadableLoadingComponentProps;
|
||||
export default dynamic;
|
||||
|
||||
2
types/next/index.d.ts
vendored
2
types/next/index.d.ts
vendored
@@ -13,9 +13,7 @@
|
||||
|
||||
import * as http from "http";
|
||||
import * as url from "url";
|
||||
|
||||
import { Response as NodeResponse } from "node-fetch";
|
||||
|
||||
import { SingletonRouter, DefaultQuery, UrlLike } from "./router";
|
||||
|
||||
declare namespace next {
|
||||
|
||||
@@ -1,25 +1,65 @@
|
||||
import dynamic, * as d from "next/dynamic";
|
||||
import * as React from "react";
|
||||
import dynamic, { LoadingComponentProps } from "next/dynamic";
|
||||
|
||||
// typically you'd use this with an esnext-style import() statement, but we'll make do without
|
||||
interface DynamicComponentProps {
|
||||
// You'd typically do this via import('./MyComponent')
|
||||
interface MyComponentProps {
|
||||
foo: string;
|
||||
bar: number;
|
||||
}
|
||||
async function getComponent() {
|
||||
return (props: DynamicComponentProps) => (
|
||||
<div>
|
||||
I'm an async component! {props.foo} {props.bar}
|
||||
</div>
|
||||
);
|
||||
}
|
||||
const MyComponent: React.StatelessComponent<MyComponentProps> = () => <div>I'm async!</div>;
|
||||
const asyncComponent = Promise.resolve(MyComponent);
|
||||
|
||||
interface LoadingComponentProps {
|
||||
baz: boolean;
|
||||
}
|
||||
// Examples from
|
||||
// https://github.com/zeit/next.js/#dynamic-import
|
||||
|
||||
const DynamicComponent = dynamic(getComponent(), {
|
||||
loading: (props: LoadingComponentProps) => <div>Loading! {props.baz}</div>,
|
||||
const LoadingComponent: React.StatelessComponent<LoadingComponentProps> = ({
|
||||
isLoading,
|
||||
error
|
||||
}) => <p>loading...</p>;
|
||||
|
||||
// 1. Basic Usage (Also does SSR)
|
||||
const DynamicComponent = dynamic(asyncComponent);
|
||||
const dynamicComponentJSX = <DynamicComponent foo="bar" />;
|
||||
|
||||
// 2. With Custom Loading Component
|
||||
const DynamicComponentWithCustomLoading = dynamic(asyncComponent, {
|
||||
loading: LoadingComponent
|
||||
});
|
||||
const dynamicComponentWithCustomLoadingJSX = <DynamicComponentWithCustomLoading foo="bar" />;
|
||||
|
||||
// 3. With No SSR
|
||||
const DynamicComponentWithNoSSR = dynamic(asyncComponent, {
|
||||
ssr: false
|
||||
});
|
||||
|
||||
const jsx = <DynamicComponent foo="five" bar={5} baz />;
|
||||
// 4. With Multiple Modules At Once
|
||||
const HelloBundle = dynamic<MyComponentProps>({
|
||||
modules: () => {
|
||||
const components = {
|
||||
Hello1: asyncComponent,
|
||||
Hello2: asyncComponent
|
||||
};
|
||||
|
||||
return components;
|
||||
},
|
||||
render: (props, { Hello1, Hello2 }) => (
|
||||
<div>
|
||||
<h1>{props.foo}</h1>
|
||||
<Hello1 />
|
||||
<Hello2 />
|
||||
</div>
|
||||
)
|
||||
});
|
||||
const helloBundleJSX = <HelloBundle foo="bar" />;
|
||||
|
||||
// 5. With plain Loadable options
|
||||
const LoadableComponent = dynamic({
|
||||
loader: () => asyncComponent,
|
||||
loading: LoadingComponent,
|
||||
delay: 200,
|
||||
timeout: 10000
|
||||
});
|
||||
|
||||
// 6. No loading
|
||||
const DynamicComponentWithNoLoading = dynamic(asyncComponent, {
|
||||
loading: () => null
|
||||
});
|
||||
|
||||
Reference in New Issue
Block a user