mirror of
https://github.com/zhigang1992/DefinitelyTyped.git
synced 2026-04-22 20:39:17 +08:00
Make react-loadable export an assignment (#22340)
* Make react-loadable export an assignment
`react-loadable` does *not* actually have a default export. This can be shown
by running:
```
> var L = require('react-loadable')
undefined
> L
{ [Function: Loadable]
Map: [Function: LoadableMap],
Capture:
{ [Function: Capture]
propTypes: { report: [Function: bound checkType] },
childContextTypes: { loadable: [Function: bound checkType] } },
preloadAll: [Function],
preloadReady: [Function] }
```
As a result, when attempting to use this with commonjs modules, an error error
is thrown when `allowSyntheticDefaultExports` is set.
```
TypeError: react_loadable_1.default is not a function
```
This PR exports the module as an assignment, so now `import * as Loadable from
'react-loadable'` should be used to import the module.
I am not entirely sure that I have used the best pattern for typings here; but
my goal was to export the proper assignment yet still allow all of the
namespace to be accessible via `(i.e.) Loadable.LoadingComponentProps`. If there
is a better way, please let me know and I will be happy to adjust!
* Use import assignment in react-loadable tests
This commit is contained in:
committed by
Ryan Cavanaugh
parent
f0b524190a
commit
9f041991c6
354
types/react-loadable/index.d.ts
vendored
354
types/react-loadable/index.d.ts
vendored
@@ -1,184 +1,190 @@
|
||||
// Type definitions for react-loadable 5.3
|
||||
// Project: https://github.com/thejameskyle/react-loadable#readme
|
||||
// Definitions by: Diogo Franco <https://github.com/Kovensky>, Oden S. <https://github.com/odensc>
|
||||
// Definitions by: Diogo Franco <https://github.com/Kovensky>, Oden S. <https://github.com/odensc>, Ian Ker-Seymer <https://github.com/ianks>
|
||||
// Definitions: https://github.com/DefinitelyTyped/DefinitelyTyped
|
||||
// TypeScript Version: 2.4
|
||||
|
||||
import * as React from 'react';
|
||||
/// <reference types="react" />
|
||||
|
||||
export interface LoadingComponentProps {
|
||||
isLoading: boolean;
|
||||
pastDelay: boolean;
|
||||
timedOut: boolean;
|
||||
error: any;
|
||||
declare namespace Loadable {
|
||||
interface LoadingComponentProps {
|
||||
isLoading: boolean;
|
||||
pastDelay: boolean;
|
||||
timedOut: boolean;
|
||||
error: any;
|
||||
}
|
||||
|
||||
type Options<Props, Exports extends object> = OptionsWithoutRender<Props> | OptionsWithRender<Props, Exports>;
|
||||
|
||||
interface CommonOptions {
|
||||
/**
|
||||
* React component displayed after delay until loader() succeeds. Also responsible for displaying errors.
|
||||
*
|
||||
* If you don't want to render anything you can pass a function that returns null
|
||||
* (this is considered a valid React component).
|
||||
*/
|
||||
// NOTE: () => null is only needed until React.SFC supports components returning null
|
||||
loading: React.ComponentType<LoadingComponentProps> | (() => null);
|
||||
/**
|
||||
* Defaults to 200, in milliseconds.
|
||||
*
|
||||
* Only show the loading component if the loader() has taken this long to succeed or error.
|
||||
*/
|
||||
delay?: number | false | null;
|
||||
/**
|
||||
* Disabled by default.
|
||||
*
|
||||
* After the specified time in milliseconds passes, the component's `timedOut` prop will be set to true.
|
||||
*/
|
||||
timeout?: number | false | null;
|
||||
|
||||
/**
|
||||
* Optional array of module paths that `Loadable.Capture`'s `report` function will be applied on during
|
||||
* server-side rendering. This helps the server know which modules were imported/used during SSR.
|
||||
* ```ts
|
||||
* Loadable({
|
||||
* loader: () => import('./my-component'),
|
||||
* modules: ['./my-component'],
|
||||
* });
|
||||
* ```
|
||||
*/
|
||||
modules?: string[];
|
||||
|
||||
/**
|
||||
* An optional function which returns an array of Webpack module ids which you can get
|
||||
* with require.resolveWeak. This is used by the client (inside `Loadable.preloadReady`) to
|
||||
* guarantee each webpack module is preloaded before the first client render.
|
||||
* ```ts
|
||||
* Loadable({
|
||||
* loader: () => import('./Foo'),
|
||||
* webpack: () => [require.resolveWeak('./Foo')],
|
||||
* });
|
||||
* ```
|
||||
*/
|
||||
webpack?: () => number[];
|
||||
}
|
||||
|
||||
interface OptionsWithoutRender<Props> extends CommonOptions {
|
||||
/**
|
||||
* Function returning a promise which returns a React component displayed on success.
|
||||
*
|
||||
* Resulting React component receives all the props passed to the generated component.
|
||||
*/
|
||||
loader(): Promise<React.ComponentType<Props> | { default: React.ComponentType<Props> }>;
|
||||
}
|
||||
|
||||
interface OptionsWithRender<Props, Exports extends object> extends CommonOptions {
|
||||
/**
|
||||
* Function returning a promise which returns an object to be passed to `render` on success.
|
||||
*/
|
||||
loader(): Promise<Exports>;
|
||||
/**
|
||||
* If you want to customize what gets rendered from your loader you can also pass `render`.
|
||||
*
|
||||
* Note: If you want to load multiple resources at once, you can also use `Loadable.Map`.
|
||||
*
|
||||
* ```ts
|
||||
* Loadable({
|
||||
* // ...
|
||||
* render(loaded, props) {
|
||||
* const Component = loaded.default;
|
||||
* return <Component {...props} />
|
||||
* }
|
||||
* });
|
||||
* ```
|
||||
*/
|
||||
render(loaded: Exports, props: Props): React.ReactNode;
|
||||
|
||||
// NOTE: render is not optional if the loader return type is not compatible with the type
|
||||
// expected in `OptionsWithoutRender`. If you do not want to provide a render function, ensure that your
|
||||
// function is returning a promise for a React.ComponentType or is the result of import()ing a module
|
||||
// that has a component as its `default` export.
|
||||
}
|
||||
|
||||
interface OptionsWithMap<Props, Exports extends { [key: string]: any }> extends CommonOptions {
|
||||
/**
|
||||
* An object containing functions which return promises, which resolve to an object to be passed to `render` on success.
|
||||
*/
|
||||
loader: {
|
||||
[P in keyof Exports]: () => Promise<Exports[P]>
|
||||
};
|
||||
/**
|
||||
* If you want to customize what gets rendered from your loader you can also pass `render`.
|
||||
*
|
||||
* Note: If you want to load multiple resources at once, you can also use `Loadable.Map`.
|
||||
*
|
||||
* ```ts
|
||||
* Loadable({
|
||||
* // ...
|
||||
* render(loaded, props) {
|
||||
* const Component = loaded.default;
|
||||
* return <Component {...props} />
|
||||
* }
|
||||
* });
|
||||
* ```
|
||||
*/
|
||||
render(loaded: Exports, props: Props): React.ReactNode;
|
||||
}
|
||||
|
||||
interface LoadableComponent {
|
||||
/**
|
||||
* The generated component has a static method preload() for calling the loader function ahead of time.
|
||||
* This is useful for scenarios where you think the user might do something next and want to load the
|
||||
* next component eagerly.
|
||||
*
|
||||
* Note: preload() intentionally does not return a promise. You should not be depending on the timing of
|
||||
* preload(). It's meant as a performance optimization, not for creating UI logic.
|
||||
*/
|
||||
preload(): void;
|
||||
}
|
||||
|
||||
interface LoadableCaptureProps {
|
||||
/**
|
||||
* Function called for every moduleName that is rendered via React Loadable.
|
||||
*/
|
||||
report: (moduleName: string) => void;
|
||||
}
|
||||
|
||||
interface Loadable {
|
||||
<Props, Exports extends object>(options: Options<Props, Exports>): React.ComponentType<Props> & LoadableComponent;
|
||||
Map<Props, Exports extends { [key: string]: any }>(options: OptionsWithMap<Props, Exports>): React.ComponentType<Props> & LoadableComponent;
|
||||
|
||||
/**
|
||||
* This will call all of the LoadableComponent.preload methods recursively until they are all
|
||||
* resolved. Allowing you to preload all of your dynamic modules in environments like the server.
|
||||
* ```ts
|
||||
* Loadable.preloadAll().then(() => {
|
||||
* app.listen(3000, () => {
|
||||
* console.log('Running on http://localhost:3000/');
|
||||
* });
|
||||
* });
|
||||
* ```
|
||||
*/
|
||||
preloadAll(): Promise<void>;
|
||||
|
||||
/**
|
||||
* Check for modules that are already loaded in the browser and call the matching
|
||||
* `LoadableComponent.preload` methods.
|
||||
* ```ts
|
||||
* window.main = () => {
|
||||
* Loadable.preloadReady().then(() => {
|
||||
* ReactDOM.hydrate(
|
||||
* <App/>,
|
||||
* document.getElementById('app'),
|
||||
* );
|
||||
* });
|
||||
* };
|
||||
* ```
|
||||
*/
|
||||
preloadReady(): Promise<void>;
|
||||
|
||||
Capture: React.ComponentType<LoadableCaptureProps>;
|
||||
}
|
||||
}
|
||||
|
||||
export type Options<Props, Exports extends object> = OptionsWithoutRender<Props> | OptionsWithRender<Props, Exports>;
|
||||
declare const LoadableExport: Loadable.Loadable;
|
||||
|
||||
export interface CommonOptions {
|
||||
/**
|
||||
* React component displayed after delay until loader() succeeds. Also responsible for displaying errors.
|
||||
*
|
||||
* If you don't want to render anything you can pass a function that returns null
|
||||
* (this is considered a valid React component).
|
||||
*/
|
||||
// NOTE: () => null is only needed until React.SFC supports components returning null
|
||||
loading: React.ComponentType<LoadingComponentProps> | (() => null);
|
||||
/**
|
||||
* Defaults to 200, in milliseconds.
|
||||
*
|
||||
* Only show the loading component if the loader() has taken this long to succeed or error.
|
||||
*/
|
||||
delay?: number | false | null;
|
||||
/**
|
||||
* Disabled by default.
|
||||
*
|
||||
* After the specified time in milliseconds passes, the component's `timedOut` prop will be set to true.
|
||||
*/
|
||||
timeout?: number | false | null;
|
||||
|
||||
/**
|
||||
* Optional array of module paths that `Loadable.Capture`'s `report` function will be applied on during
|
||||
* server-side rendering. This helps the server know which modules were imported/used during SSR.
|
||||
* ```ts
|
||||
* Loadable({
|
||||
* loader: () => import('./my-component'),
|
||||
* modules: ['./my-component'],
|
||||
* });
|
||||
* ```
|
||||
*/
|
||||
modules?: string[];
|
||||
|
||||
/**
|
||||
* An optional function which returns an array of Webpack module ids which you can get
|
||||
* with require.resolveWeak. This is used by the client (inside `Loadable.preloadReady`) to
|
||||
* guarantee each webpack module is preloaded before the first client render.
|
||||
* ```ts
|
||||
* Loadable({
|
||||
* loader: () => import('./Foo'),
|
||||
* webpack: () => [require.resolveWeak('./Foo')],
|
||||
* });
|
||||
* ```
|
||||
*/
|
||||
webpack?: () => number[];
|
||||
/* tslint:disable-next-line */
|
||||
declare module "react-loadable" {
|
||||
export = LoadableExport;
|
||||
}
|
||||
|
||||
export interface OptionsWithoutRender<Props> extends CommonOptions {
|
||||
/**
|
||||
* Function returning a promise which returns a React component displayed on success.
|
||||
*
|
||||
* Resulting React component receives all the props passed to the generated component.
|
||||
*/
|
||||
loader(): Promise<React.ComponentType<Props> | { default: React.ComponentType<Props> }>;
|
||||
}
|
||||
|
||||
export interface OptionsWithRender<Props, Exports extends object> extends CommonOptions {
|
||||
/**
|
||||
* Function returning a promise which returns an object to be passed to `render` on success.
|
||||
*/
|
||||
loader(): Promise<Exports>;
|
||||
/**
|
||||
* If you want to customize what gets rendered from your loader you can also pass `render`.
|
||||
*
|
||||
* Note: If you want to load multiple resources at once, you can also use `Loadable.Map`.
|
||||
*
|
||||
* ```ts
|
||||
* Loadable({
|
||||
* // ...
|
||||
* render(loaded, props) {
|
||||
* const Component = loaded.default;
|
||||
* return <Component {...props} />
|
||||
* }
|
||||
* });
|
||||
* ```
|
||||
*/
|
||||
render(loaded: Exports, props: Props): React.ReactNode;
|
||||
|
||||
// NOTE: render is not optional if the loader return type is not compatible with the type
|
||||
// expected in `OptionsWithoutRender`. If you do not want to provide a render function, ensure that your
|
||||
// function is returning a promise for a React.ComponentType or is the result of import()ing a module
|
||||
// that has a component as its `default` export.
|
||||
}
|
||||
|
||||
export interface OptionsWithMap<Props, Exports extends { [key: string]: any }> extends CommonOptions {
|
||||
/**
|
||||
* An object containing functions which return promises, which resolve to an object to be passed to `render` on success.
|
||||
*/
|
||||
loader: {
|
||||
[P in keyof Exports]: () => Promise<Exports[P]>
|
||||
};
|
||||
/**
|
||||
* If you want to customize what gets rendered from your loader you can also pass `render`.
|
||||
*
|
||||
* Note: If you want to load multiple resources at once, you can also use `Loadable.Map`.
|
||||
*
|
||||
* ```ts
|
||||
* Loadable({
|
||||
* // ...
|
||||
* render(loaded, props) {
|
||||
* const Component = loaded.default;
|
||||
* return <Component {...props} />
|
||||
* }
|
||||
* });
|
||||
* ```
|
||||
*/
|
||||
render(loaded: Exports, props: Props): React.ReactNode;
|
||||
}
|
||||
|
||||
export interface LoadableComponent {
|
||||
/**
|
||||
* The generated component has a static method preload() for calling the loader function ahead of time.
|
||||
* This is useful for scenarios where you think the user might do something next and want to load the
|
||||
* next component eagerly.
|
||||
*
|
||||
* Note: preload() intentionally does not return a promise. You should not be depending on the timing of
|
||||
* preload(). It's meant as a performance optimization, not for creating UI logic.
|
||||
*/
|
||||
preload(): void;
|
||||
}
|
||||
|
||||
export interface LoadableCaptureProps {
|
||||
/**
|
||||
* Function called for every moduleName that is rendered via React Loadable.
|
||||
*/
|
||||
report: (moduleName: string) => void;
|
||||
}
|
||||
|
||||
export interface Loadable {
|
||||
<Props, Exports extends object>(options: Options<Props, Exports>): React.ComponentType<Props> & LoadableComponent;
|
||||
Map<Props, Exports extends { [key: string]: any }>(options: OptionsWithMap<Props, Exports>): React.ComponentType<Props> & LoadableComponent;
|
||||
|
||||
/**
|
||||
* This will call all of the LoadableComponent.preload methods recursively until they are all
|
||||
* resolved. Allowing you to preload all of your dynamic modules in environments like the server.
|
||||
* ```ts
|
||||
* Loadable.preloadAll().then(() => {
|
||||
* app.listen(3000, () => {
|
||||
* console.log('Running on http://localhost:3000/');
|
||||
* });
|
||||
* });
|
||||
* ```
|
||||
*/
|
||||
preloadAll(): Promise<void>;
|
||||
|
||||
/**
|
||||
* Check for modules that are already loaded in the browser and call the matching
|
||||
* `LoadableComponent.preload` methods.
|
||||
* ```ts
|
||||
* window.main = () => {
|
||||
* Loadable.preloadReady().then(() => {
|
||||
* ReactDOM.hydrate(
|
||||
* <App/>,
|
||||
* document.getElementById('app'),
|
||||
* );
|
||||
* });
|
||||
* };
|
||||
* ```
|
||||
*/
|
||||
preloadReady(): Promise<void>;
|
||||
|
||||
Capture: React.ComponentType<LoadableCaptureProps>;
|
||||
}
|
||||
|
||||
declare const LoadableExport: Loadable;
|
||||
export default LoadableExport;
|
||||
|
||||
@@ -1,7 +1,7 @@
|
||||
import * as React from 'react';
|
||||
import Loadable, { LoadingComponentProps } from 'react-loadable';
|
||||
import Loadable = require('react-loadable');
|
||||
|
||||
class LoadingComponent extends React.Component<LoadingComponentProps> {
|
||||
class LoadingComponent extends React.Component<Loadable.LoadingComponentProps> {
|
||||
render() {
|
||||
return (
|
||||
<div>
|
||||
|
||||
Reference in New Issue
Block a user