UNPKG

7.03 kBTypeScriptView Raw
1/// <reference types="react" />
2
3declare namespace LoadableExport {
4 interface LoadingComponentProps {
5 isLoading: boolean;
6 pastDelay: boolean;
7 timedOut: boolean;
8 error: any;
9 retry: () => void;
10 }
11
12 type Options<Props, Exports extends object> = OptionsWithoutRender<Props> | OptionsWithRender<Props, Exports>;
13
14 interface CommonOptions {
15 /**
16 * React component displayed after delay until loader() succeeds. Also responsible for displaying errors.
17 *
18 * If you don't want to render anything you can pass a function that returns null
19 * (this is considered a valid React component).
20 */
21 loading: React.ComponentType<LoadingComponentProps>;
22 /**
23 * Defaults to 200, in milliseconds.
24 *
25 * Only show the loading component if the loader() has taken this long to succeed or error.
26 */
27 delay?: number | false | null | undefined;
28 /**
29 * Disabled by default.
30 *
31 * After the specified time in milliseconds passes, the component's `timedOut` prop will be set to true.
32 */
33 timeout?: number | false | null | undefined;
34
35 /**
36 * Optional array of module paths that `Loadable.Capture`'s `report` function will be applied on during
37 * server-side rendering. This helps the server know which modules were imported/used during SSR.
38 * ```ts
39 * Loadable({
40 * loader: () => import('./my-component'),
41 * modules: ['./my-component'],
42 * });
43 * ```
44 */
45 modules?: string[] | undefined;
46
47 /**
48 * An optional function which returns an array of Webpack module ids which you can get
49 * with require.resolveWeak. This is used by the client (inside `Loadable.preloadReady`) to
50 * guarantee each webpack module is preloaded before the first client render.
51 * ```ts
52 * Loadable({
53 * loader: () => import('./Foo'),
54 * webpack: () => [require.resolveWeak('./Foo')],
55 * });
56 * ```
57 */
58 webpack?: (() => Array<string | number>) | undefined;
59 }
60
61 interface OptionsWithoutRender<Props> extends CommonOptions {
62 /**
63 * Function returning a promise which returns a React component displayed on success.
64 *
65 * Resulting React component receives all the props passed to the generated component.
66 */
67 loader(): Promise<React.ComponentType<Props> | { default: React.ComponentType<Props> }>;
68 }
69
70 interface OptionsWithRender<Props, Exports extends object> extends CommonOptions {
71 /**
72 * Function returning a promise which returns an object to be passed to `render` on success.
73 */
74 loader(): Promise<Exports>;
75 /**
76 * If you want to customize what gets rendered from your loader you can also pass `render`.
77 *
78 * Note: If you want to load multiple resources at once, you can also use `Loadable.Map`.
79 *
80 * ```ts
81 * Loadable({
82 * // ...
83 * render(loaded, props) {
84 * const Component = loaded.default;
85 * return <Component {...props} />
86 * }
87 * });
88 * ```
89 */
90 render(loaded: Exports, props: Props): React.ReactNode;
91
92 // NOTE: render is not optional if the loader return type is not compatible with the type
93 // expected in `OptionsWithoutRender`. If you do not want to provide a render function, ensure that your
94 // function is returning a promise for a React.ComponentType or is the result of import()ing a module
95 // that has a component as its `default` export.
96 }
97
98 interface OptionsWithMap<Props, Exports extends { [key: string]: any }> extends CommonOptions {
99 /**
100 * An object containing functions which return promises, which resolve to an object to be passed to `render` on success.
101 */
102 loader: {
103 [P in keyof Exports]: () => Promise<Exports[P]>;
104 };
105 /**
106 * If you want to customize what gets rendered from your loader you can also pass `render`.
107 *
108 * Note: If you want to load multiple resources at once, you can also use `Loadable.Map`.
109 *
110 * ```ts
111 * Loadable({
112 * // ...
113 * render(loaded, props) {
114 * const Component = loaded.default;
115 * return <Component {...props} />
116 * }
117 * });
118 * ```
119 */
120 render(loaded: Exports, props: Props): React.ReactNode;
121 }
122
123 interface LoadableComponent {
124 /**
125 * The generated component has a static method preload() for calling the loader function ahead of time.
126 * This is useful for scenarios where you think the user might do something next and want to load the
127 * next component eagerly.
128 *
129 * Note: preload() intentionally does not return a promise. You should not be depending on the timing of
130 * preload(). It's meant as a performance optimization, not for creating UI logic.
131 */
132 preload(): void;
133 }
134
135 interface LoadableCaptureProps {
136 /**
137 * Function called for every moduleName that is rendered via React Loadable.
138 */
139 report: (moduleName: string) => void;
140 }
141
142 interface Loadable {
143 <Props, Exports extends object>(
144 options: Options<Props, Exports>,
145 ): React.ComponentType<Props> & LoadableComponent;
146 Map<Props, Exports extends { [key: string]: any }>(
147 options: OptionsWithMap<Props, Exports>,
148 ): React.ComponentType<Props> & LoadableComponent;
149
150 /**
151 * This will call all of the LoadableComponent.preload methods recursively until they are all
152 * resolved. Allowing you to preload all of your dynamic modules in environments like the server.
153 * ```ts
154 * Loadable.preloadAll().then(() => {
155 * app.listen(3000, () => {
156 * console.log('Running on http://localhost:3000/');
157 * });
158 * });
159 * ```
160 */
161 preloadAll(): Promise<void>;
162
163 /**
164 * Check for modules that are already loaded in the browser and call the matching
165 * `LoadableComponent.preload` methods.
166 * ```ts
167 * window.main = () => {
168 * Loadable.preloadReady().then(() => {
169 * ReactDOM.hydrate(
170 * <App/>,
171 * document.getElementById('app'),
172 * );
173 * });
174 * };
175 * ```
176 */
177 preloadReady(): Promise<void>;
178
179 Capture: React.ComponentType<LoadableCaptureProps>;
180 }
181}
182
183declare const LoadableExport: LoadableExport.Loadable;
184
185/* eslint-disable-next-line @definitelytyped/no-declare-current-package */
186declare module "react-loadable" {
187 export = LoadableExport;
188}