// Definitions: https://github.com/DefinitelyTyped/DefinitelyTyped
// TypeScript Version: 2.8
// NOTE: Users of the upcoming React 18 release should add a reference
// to 'react/next' in their project. See next.d.ts's top comment
// for reference and documentation on how exactly to do it.
// NOTE: Users of the `experimental` builds of React should add a reference
// to 'react/experimental' in their project. See experimental.d.ts's top comment
// for reference and documentation on how exactly to do it.
///
import * as CSS from 'csstype';
import * as PropTypes from 'prop-types';
import { Interaction as SchedulerInteraction } from 'scheduler/tracing';
type NativeAnimationEvent = AnimationEvent;
type NativeClipboardEvent = ClipboardEvent;
type NativeCompositionEvent = CompositionEvent;
type NativeDragEvent = DragEvent;
type NativeFocusEvent = FocusEvent;
type NativeKeyboardEvent = KeyboardEvent;
type NativeMouseEvent = MouseEvent;
type NativeTouchEvent = TouchEvent;
type NativePointerEvent = PointerEvent;
type NativeTransitionEvent = TransitionEvent;
type NativeUIEvent = UIEvent;
type NativeWheelEvent = WheelEvent;
type Booleanish = boolean | 'true' | 'false';
declare const UNDEFINED_VOID_ONLY: unique symbol;
// Destructors are only allowed to return void.
type Destructor = () => void | { [UNDEFINED_VOID_ONLY]: never };
// tslint:disable-next-line:export-just-namespace
export = React;
export as namespace React;
declare namespace React {
//
// React Elements
// ----------------------------------------------------------------------
type ElementType =
{
[K in keyof JSX.IntrinsicElements]: P extends JSX.IntrinsicElements[K] ? K : never
}[keyof JSX.IntrinsicElements] |
ComponentType
;
/**
* @deprecated Please use `ElementType`
*/
type ReactType
= ElementType
;
type ComponentType
= ComponentClass
| FunctionComponent
;
type JSXElementConstructor
=
| ((props: P) => ReactElement | null)
| (new (props: P) => Component);
interface RefObject {
readonly current: T | null;
}
type RefCallback = { bivarianceHack(instance: T | null): void }["bivarianceHack"];
type Ref = RefCallback | RefObject | null;
type LegacyRef = string | Ref;
/**
* Gets the instance type for a React element. The instance will be different for various component types:
*
* - React class components will be the class instance. So if you had `class Foo extends React.Component<{}> {}`
* and used `React.ElementRef` then the type would be the instance of `Foo`.
* - React stateless functional components do not have a backing instance and so `React.ElementRef`
* (when `Bar` is `function Bar() {}`) will give you the `undefined` type.
* - JSX intrinsics like `div` will give you their DOM instance. For `React.ElementRef<'div'>` that would be
* `HTMLDivElement`. For `React.ElementRef<'input'>` that would be `HTMLInputElement`.
* - React stateless functional components that forward a `ref` will give you the `ElementRef` of the forwarded
* to component.
*
* `C` must be the type _of_ a React component so you need to use typeof as in React.ElementRef.
*
* @todo In Flow, this works a little different with forwarded refs and the `AbstractComponent` that
* `React.forwardRef()` returns.
*/
type ElementRef<
C extends
| ForwardRefExoticComponent
| { new (props: any): Component }
| ((props: any, context?: any) => ReactElement | null)
| keyof JSX.IntrinsicElements
> =
// need to check first if `ref` is a valid prop for ts@3.0
// otherwise it will infer `{}` instead of `never`
"ref" extends keyof ComponentPropsWithRef
? NonNullable["ref"]> extends Ref<
infer Instance
>
? Instance
: never
: never;
type ComponentState = any;
type Key = string | number;
/**
* @internal You shouldn't need to use this type since you never see these attributes
* inside your component or have to validate them.
*/
interface Attributes {
key?: Key | null | undefined;
}
interface RefAttributes extends Attributes {
ref?: Ref | undefined;
}
interface ClassAttributes extends Attributes {
ref?: LegacyRef | undefined;
}
interface ReactElement = string | JSXElementConstructor> {
type: T;
props: P;
key: Key | null;
}
interface ReactComponentElement<
T extends keyof JSX.IntrinsicElements | JSXElementConstructor,
P = Pick, Exclude, 'key' | 'ref'>>
> extends ReactElement> { }
/**
* @deprecated Please use `FunctionComponentElement`
*/
type SFCElement
= FunctionComponentElement
;
interface FunctionComponentElement
extends ReactElement
> {
ref?: ('ref' extends keyof P ? P extends { ref?: infer R | undefined } ? R : never : never) | undefined;
}
type CElement
> = ComponentElement
;
interface ComponentElement
> extends ReactElement
> {
ref?: LegacyRef | undefined;
}
type ClassicElement = CElement
>;
// string fallback for custom web-components
interface DOMElement
| SVGAttributes, T extends Element> extends ReactElement {
ref: LegacyRef;
}
// ReactHTML for ReactHTMLElement
interface ReactHTMLElement extends DetailedReactHTMLElement, T> { }
interface DetailedReactHTMLElement, T extends HTMLElement> extends DOMElement
{
type: keyof ReactHTML;
}
// ReactSVG for ReactSVGElement
interface ReactSVGElement extends DOMElement, SVGElement> {
type: keyof ReactSVG;
}
interface ReactPortal extends ReactElement {
key: Key | null;
children: ReactNode;
}
//
// Factories
// ----------------------------------------------------------------------
type Factory = (props?: Attributes & P, ...children: ReactNode[]) => ReactElement
;
/**
* @deprecated Please use `FunctionComponentFactory`
*/
type SFCFactory
= FunctionComponentFactory
;
type FunctionComponentFactory
= (props?: Attributes & P, ...children: ReactNode[]) => FunctionComponentElement
;
type ComponentFactory
> =
(props?: ClassAttributes & P, ...children: ReactNode[]) => CElement;
type CFactory
> = ComponentFactory
;
type ClassicFactory
= CFactory
>;
type DOMFactory
, T extends Element> =
(props?: ClassAttributes & P | null, ...children: ReactNode[]) => DOMElement;
interface HTMLFactory extends DetailedHTMLFactory, T> {}
interface DetailedHTMLFactory, T extends HTMLElement> extends DOMFactory
{
(props?: ClassAttributes & P | null, ...children: ReactNode[]): DetailedReactHTMLElement;
}
interface SVGFactory extends DOMFactory, SVGElement> {
(props?: ClassAttributes & SVGAttributes | null, ...children: ReactNode[]): ReactSVGElement;
}
//
// React Nodes
// http://facebook.github.io/react/docs/glossary.html
// ----------------------------------------------------------------------
type ReactText = string | number;
type ReactChild = ReactElement | ReactText;
/**
* @deprecated Use either `ReactNode[]` if you need an array or `Iterable` if its passed to a host component.
*/
interface ReactNodeArray extends ReadonlyArray {}
type ReactFragment = {} | Iterable;
type ReactNode = ReactChild | ReactFragment | ReactPortal | boolean | null | undefined;
//
// Top Level API
// ----------------------------------------------------------------------
// DOM Elements
function createFactory(
type: keyof ReactHTML): HTMLFactory;
function createFactory(
type: keyof ReactSVG): SVGFactory;
function createFactory, T extends Element>(
type: string): DOMFactory
;
// Custom components
function createFactory
(type: FunctionComponent
): FunctionComponentFactory
;
function createFactory
(
type: ClassType
, ClassicComponentClass
>): CFactory
>;
function createFactory
, C extends ComponentClass
>(
type: ClassType
): CFactory
;
function createFactory
(type: ComponentClass
): Factory
;
// DOM Elements
// TODO: generalize this to everything in `keyof ReactHTML`, not just "input"
function createElement(
type: "input",
props?: InputHTMLAttributes & ClassAttributes | null,
...children: ReactNode[]): DetailedReactHTMLElement, HTMLInputElement>;
function createElement, T extends HTMLElement>(
type: keyof ReactHTML,
props?: ClassAttributes & P | null,
...children: ReactNode[]): DetailedReactHTMLElement;
function createElement
, T extends SVGElement>(
type: keyof ReactSVG,
props?: ClassAttributes & P | null,
...children: ReactNode[]): ReactSVGElement;
function createElement, T extends Element>(
type: string,
props?: ClassAttributes & P | null,
...children: ReactNode[]): DOMElement;
// Custom components
function createElement
(
type: FunctionComponent
,
props?: Attributes & P | null,
...children: ReactNode[]): FunctionComponentElement
;
function createElement
(
type: ClassType
, ClassicComponentClass
>,
props?: ClassAttributes> & P | null,
...children: ReactNode[]): CElement>;
function createElement
, C extends ComponentClass
>(
type: ClassType
,
props?: ClassAttributes & P | null,
...children: ReactNode[]): CElement;
function createElement
(
type: FunctionComponent
| ComponentClass
| string,
props?: Attributes & P | null,
...children: ReactNode[]): ReactElement
;
// DOM Elements
// ReactHTMLElement
function cloneElement
, T extends HTMLElement>(
element: DetailedReactHTMLElement
,
props?: P,
...children: ReactNode[]): DetailedReactHTMLElement
;
// ReactHTMLElement, less specific
function cloneElement
, T extends HTMLElement>(
element: ReactHTMLElement,
props?: P,
...children: ReactNode[]): ReactHTMLElement;
// SVGElement
function cloneElement, T extends SVGElement>(
element: ReactSVGElement,
props?: P,
...children: ReactNode[]): ReactSVGElement;
// DOM Element (has to be the last, because type checking stops at first overload that fits)
function cloneElement
, T extends Element>(
element: DOMElement
,
props?: DOMAttributes & P,
...children: ReactNode[]): DOMElement;
// Custom components
function cloneElement
(
element: FunctionComponentElement
,
props?: Partial
& Attributes,
...children: ReactNode[]): FunctionComponentElement
;
function cloneElement
>(
element: CElement
,
props?: Partial
& ClassAttributes,
...children: ReactNode[]): CElement;
function cloneElement
(
element: ReactElement
,
props?: Partial
& Attributes,
...children: ReactNode[]): ReactElement
;
// Context via RenderProps
interface ProviderProps {
value: T;
children?: ReactNode | undefined;
}
interface ConsumerProps {
children: (value: T) => ReactNode;
}
// TODO: similar to how Fragment is actually a symbol, the values returned from createContext,
// forwardRef and memo are actually objects that are treated specially by the renderer; see:
// https://github.com/facebook/react/blob/v16.6.0/packages/react/src/ReactContext.js#L35-L48
// https://github.com/facebook/react/blob/v16.6.0/packages/react/src/forwardRef.js#L42-L45
// https://github.com/facebook/react/blob/v16.6.0/packages/react/src/memo.js#L27-L31
// However, we have no way of telling the JSX parser that it's a JSX element type or its props other than
// by pretending to be a normal component.
//
// We don't just use ComponentType or FunctionComponent types because you are not supposed to attach statics to this
// object, but rather to the original function.
interface ExoticComponent {
/**
* **NOTE**: Exotic components are not callable.
*/
(props: P): (ReactElement|null);
readonly $$typeof: symbol;
}
interface NamedExoticComponent
extends ExoticComponent
{
displayName?: string | undefined;
}
interface ProviderExoticComponent
extends ExoticComponent
{
propTypes?: WeakValidationMap
| undefined;
}
type ContextType> = C extends Context ? T : never;
// NOTE: only the Context object itself can get a displayName
// https://github.com/facebook/react-devtools/blob/e0b854e4c/backend/attachRendererFiber.js#L310-L325
type Provider = ProviderExoticComponent>;
type Consumer = ExoticComponent>;
interface Context {
Provider: Provider;
Consumer: Consumer;
displayName?: string | undefined;
}
function createContext(
// If you thought this should be optional, see
// https://github.com/DefinitelyTyped/DefinitelyTyped/pull/24509#issuecomment-382213106
defaultValue: T,
): Context;
function isValidElement(object: {} | null | undefined): object is ReactElement
;
const Children: ReactChildren;
const Fragment: ExoticComponent<{ children?: ReactNode | undefined }>;
const StrictMode: ExoticComponent<{ children?: ReactNode | undefined }>;
interface SuspenseProps {
children?: ReactNode | undefined;
/** A fallback react tree to show when a Suspense child (like React.lazy) suspends */
fallback: NonNullable|null;
}
/**
* This feature is not yet available for server-side rendering.
* Suspense support will be added in a later release.
*/
const Suspense: ExoticComponent;
const version: string;
/**
* {@link https://reactjs.org/docs/profiler.html#onrender-callback Profiler API}
*/
type ProfilerOnRenderCallback = (
id: string,
phase: "mount" | "update",
actualDuration: number,
baseDuration: number,
startTime: number,
commitTime: number,
interactions: Set,
) => void;
interface ProfilerProps {
children?: ReactNode | undefined;
id: string;
onRender: ProfilerOnRenderCallback;
}
const Profiler: ExoticComponent;
//
// Component API
// ----------------------------------------------------------------------
type ReactInstance = Component | Element;
// Base component for plain JS classes
interface Component extends ComponentLifecycle
{ }
class Component
{
// tslint won't let me format the sample code in a way that vscode likes it :(
/**
* If set, `this.context` will be set at runtime to the current value of the given Context.
*
* Usage:
*
* ```ts
* type MyContext = number
* const Ctx = React.createContext(0)
*
* class Foo extends React.Component {
* static contextType = Ctx
* context!: React.ContextType
* render () {
* return <>My context's value: {this.context}>;
* }
* }
* ```
*
* @see https://reactjs.org/docs/context.html#classcontexttype
*/
static contextType?: Context | undefined;
/**
* If using the new style context, re-declare this in your class to be the
* `React.ContextType` of your `static contextType`.
* Should be used with type annotation or static contextType.
*
* ```ts
* static contextType = MyContext
* // For TS pre-3.7:
* context!: React.ContextType
* // For TS 3.7 and above:
* declare context: React.ContextType
* ```
*
* @see https://reactjs.org/docs/context.html
*/
// TODO (TypeScript 3.0): unknown
context: any;
constructor(props: Readonly | P);
/**
* @deprecated
* @see https://reactjs.org/docs/legacy-context.html
*/
constructor(props: P, context: any);
// We MUST keep setState() as a unified signature because it allows proper checking of the method return type.
// See: https://github.com/DefinitelyTyped/DefinitelyTyped/issues/18365#issuecomment-351013257
// Also, the ` | S` allows intellisense to not be dumbisense
setState(
state: ((prevState: Readonly, props: Readonly) => (Pick | S | null)) | (Pick | S | null),
callback?: () => void
): void;
forceUpdate(callback?: () => void): void;
render(): ReactNode;
// React.Props is now deprecated, which means that the `children`
// property is not available on `P` by default, even though you can
// always pass children as variadic arguments to `createElement`.
// In the future, if we can define its call signature conditionally
// on the existence of `children` in `P`, then we should remove this.
readonly props: Readonly & Readonly<{ children?: ReactNode | undefined }>;
state: Readonly;
/**
* @deprecated
* https://reactjs.org/docs/refs-and-the-dom.html#legacy-api-string-refs
*/
refs: {
[key: string]: ReactInstance
};
}
class PureComponent
extends Component
{ }
interface ClassicComponent
extends Component
{
replaceState(nextState: S, callback?: () => void): void;
isMounted(): boolean;
getInitialState?(): S;
}
interface ChildContextProvider {
getChildContext(): CC;
}
//
// Class Interfaces
// ----------------------------------------------------------------------
/**
* @deprecated as of recent React versions, function components can no
* longer be considered 'stateless'. Please use `FunctionComponent` instead.
*
* @see [React Hooks](https://reactjs.org/docs/hooks-intro.html)
*/
type SFC = FunctionComponent
;
/**
* @deprecated as of recent React versions, function components can no
* longer be considered 'stateless'. Please use `FunctionComponent` instead.
*
* @see [React Hooks](https://reactjs.org/docs/hooks-intro.html)
*/
type StatelessComponent
= FunctionComponent
;
type FC
= FunctionComponent
;
interface FunctionComponent
{
(props: PropsWithChildren
, context?: any): ReactElement | null;
propTypes?: WeakValidationMap | undefined;
contextTypes?: ValidationMap | undefined;
defaultProps?: Partial | undefined;
displayName?: string | undefined;
}
type VFC
= VoidFunctionComponent
;
interface VoidFunctionComponent
{
(props: P, context?: any): ReactElement | null;
propTypes?: WeakValidationMap | undefined;
contextTypes?: ValidationMap | undefined;
defaultProps?: Partial | undefined;
displayName?: string | undefined;
}
type ForwardedRef = ((instance: T | null) => void) | MutableRefObject | null;
interface ForwardRefRenderFunction {
(props: PropsWithChildren, ref: ForwardedRef): ReactElement | null;
displayName?: string | undefined;
// explicit rejected with `never` required due to
// https://github.com/microsoft/TypeScript/issues/36826
/**
* defaultProps are not supported on render functions
*/
defaultProps?: never | undefined;
/**
* propTypes are not supported on render functions
*/
propTypes?: never | undefined;
}
/**
* @deprecated Use ForwardRefRenderFunction. forwardRef doesn't accept a
* "real" component.
*/
interface RefForwardingComponent extends ForwardRefRenderFunction {}
interface ComponentClass extends StaticLifecycle
{
new (props: P, context?: any): Component
;
propTypes?: WeakValidationMap
| undefined;
contextType?: Context | undefined;
contextTypes?: ValidationMap | undefined;
childContextTypes?: ValidationMap | undefined;
defaultProps?: Partial | undefined;
displayName?: string | undefined;
}
interface ClassicComponentClass
extends ComponentClass
{
new (props: P, context?: any): ClassicComponent
;
getDefaultProps?(): P;
}
/**
* We use an intersection type to infer multiple type parameters from
* a single argument, which is useful for many top-level API defs.
* See https://github.com/Microsoft/TypeScript/issues/7234 for more info.
*/
type ClassType
, C extends ComponentClass
> =
C &
(new (props: P, context?: any) => T);
//
// Component Specs and Lifecycle
// ----------------------------------------------------------------------
// This should actually be something like `Lifecycle
| DeprecatedLifecycle
`,
// as React will _not_ call the deprecated lifecycle methods if any of the new lifecycle
// methods are present.
interface ComponentLifecycle
extends NewLifecycle
, DeprecatedLifecycle
{
/**
* Called immediately after a component is mounted. Setting state here will trigger re-rendering.
*/
componentDidMount?(): void;
/**
* Called to determine whether the change in props and state should trigger a re-render.
*
* `Component` always returns true.
* `PureComponent` implements a shallow comparison on props and state and returns true if any
* props or states have changed.
*
* If false is returned, `Component#render`, `componentWillUpdate`
* and `componentDidUpdate` will not be called.
*/
shouldComponentUpdate?(nextProps: Readonly
, nextState: Readonly, nextContext: any): boolean;
/**
* Called immediately before a component is destroyed. Perform any necessary cleanup in this method, such as
* cancelled network requests, or cleaning up any DOM elements created in `componentDidMount`.
*/
componentWillUnmount?(): void;
/**
* Catches exceptions generated in descendant components. Unhandled exceptions will cause
* the entire component tree to unmount.
*/
componentDidCatch?(error: Error, errorInfo: ErrorInfo): void;
}
// Unfortunately, we have no way of declaring that the component constructor must implement this
interface StaticLifecycle
{
getDerivedStateFromProps?: GetDerivedStateFromProps
| undefined;
getDerivedStateFromError?: GetDerivedStateFromError
| undefined;
}
type GetDerivedStateFromProps
=
/**
* Returns an update to a component's state based on its new props and old state.
*
* Note: its presence prevents any of the deprecated lifecycle methods from being invoked
*/
(nextProps: Readonly
, prevState: S) => Partial | null;
type GetDerivedStateFromError
=
/**
* This lifecycle is invoked after an error has been thrown by a descendant component.
* It receives the error that was thrown as a parameter and should return a value to update state.
*
* Note: its presence prevents any of the deprecated lifecycle methods from being invoked
*/
(error: any) => Partial | null;
// This should be "infer SS" but can't use it yet
interface NewLifecycle
{
/**
* Runs before React applies the result of `render` to the document, and
* returns an object to be given to componentDidUpdate. Useful for saving
* things such as scroll position before `render` causes changes to it.
*
* Note: the presence of getSnapshotBeforeUpdate prevents any of the deprecated
* lifecycle events from running.
*/
getSnapshotBeforeUpdate?(prevProps: Readonly
, prevState: Readonly): SS | null;
/**
* Called immediately after updating occurs. Not called for the initial render.
*
* The snapshot is only present if getSnapshotBeforeUpdate is present and returns non-null.
*/
componentDidUpdate?(prevProps: Readonly
, prevState: Readonly, snapshot?: SS): void;
}
interface DeprecatedLifecycle
{
/**
* Called immediately before mounting occurs, and before `Component#render`.
* Avoid introducing any side-effects or subscriptions in this method.
*
* Note: the presence of getSnapshotBeforeUpdate or getDerivedStateFromProps
* prevents this from being invoked.
*
* @deprecated 16.3, use componentDidMount or the constructor instead; will stop working in React 17
* @see https://reactjs.org/blog/2018/03/27/update-on-async-rendering.html#initializing-state
* @see https://reactjs.org/blog/2018/03/27/update-on-async-rendering.html#gradual-migration-path
*/
componentWillMount?(): void;
/**
* Called immediately before mounting occurs, and before `Component#render`.
* Avoid introducing any side-effects or subscriptions in this method.
*
* This method will not stop working in React 17.
*
* Note: the presence of getSnapshotBeforeUpdate or getDerivedStateFromProps
* prevents this from being invoked.
*
* @deprecated 16.3, use componentDidMount or the constructor instead
* @see https://reactjs.org/blog/2018/03/27/update-on-async-rendering.html#initializing-state
* @see https://reactjs.org/blog/2018/03/27/update-on-async-rendering.html#gradual-migration-path
*/
UNSAFE_componentWillMount?(): void;
/**
* Called when the component may be receiving new props.
* React may call this even if props have not changed, so be sure to compare new and existing
* props if you only want to handle changes.
*
* Calling `Component#setState` generally does not trigger this method.
*
* Note: the presence of getSnapshotBeforeUpdate or getDerivedStateFromProps
* prevents this from being invoked.
*
* @deprecated 16.3, use static getDerivedStateFromProps instead; will stop working in React 17
* @see https://reactjs.org/blog/2018/03/27/update-on-async-rendering.html#updating-state-based-on-props
* @see https://reactjs.org/blog/2018/03/27/update-on-async-rendering.html#gradual-migration-path
*/
componentWillReceiveProps?(nextProps: Readonly
, nextContext: any): void;
/**
* Called when the component may be receiving new props.
* React may call this even if props have not changed, so be sure to compare new and existing
* props if you only want to handle changes.
*
* Calling `Component#setState` generally does not trigger this method.
*
* This method will not stop working in React 17.
*
* Note: the presence of getSnapshotBeforeUpdate or getDerivedStateFromProps
* prevents this from being invoked.
*
* @deprecated 16.3, use static getDerivedStateFromProps instead
* @see https://reactjs.org/blog/2018/03/27/update-on-async-rendering.html#updating-state-based-on-props
* @see https://reactjs.org/blog/2018/03/27/update-on-async-rendering.html#gradual-migration-path
*/
UNSAFE_componentWillReceiveProps?(nextProps: Readonly
, nextContext: any): void;
/**
* Called immediately before rendering when new props or state is received. Not called for the initial render.
*
* Note: You cannot call `Component#setState` here.
*
* Note: the presence of getSnapshotBeforeUpdate or getDerivedStateFromProps
* prevents this from being invoked.
*
* @deprecated 16.3, use getSnapshotBeforeUpdate instead; will stop working in React 17
* @see https://reactjs.org/blog/2018/03/27/update-on-async-rendering.html#reading-dom-properties-before-an-update
* @see https://reactjs.org/blog/2018/03/27/update-on-async-rendering.html#gradual-migration-path
*/
componentWillUpdate?(nextProps: Readonly
, nextState: Readonly, nextContext: any): void;
/**
* Called immediately before rendering when new props or state is received. Not called for the initial render.
*
* Note: You cannot call `Component#setState` here.
*
* This method will not stop working in React 17.
*
* Note: the presence of getSnapshotBeforeUpdate or getDerivedStateFromProps
* prevents this from being invoked.
*
* @deprecated 16.3, use getSnapshotBeforeUpdate instead
* @see https://reactjs.org/blog/2018/03/27/update-on-async-rendering.html#reading-dom-properties-before-an-update
* @see https://reactjs.org/blog/2018/03/27/update-on-async-rendering.html#gradual-migration-path
*/
UNSAFE_componentWillUpdate?(nextProps: Readonly
, nextState: Readonly, nextContext: any): void;
}
interface Mixin
extends ComponentLifecycle
{
mixins?: Array> | undefined;
statics?: {
[key: string]: any;
} | undefined;
displayName?: string | undefined;
propTypes?: ValidationMap | undefined;
contextTypes?: ValidationMap | undefined;
childContextTypes?: ValidationMap | undefined;
getDefaultProps?(): P;
getInitialState?(): S;
}
interface ComponentSpec extends Mixin
{
render(): ReactNode;
[propertyName: string]: any;
}
function createRef(): RefObject;
// will show `ForwardRef(${Component.displayName || Component.name})` in devtools by default,
// but can be given its own specific name
interface ForwardRefExoticComponent extends NamedExoticComponent
{
defaultProps?: Partial
| undefined;
propTypes?: WeakValidationMap
| undefined;
}
function forwardRef(render: ForwardRefRenderFunction): ForwardRefExoticComponent & RefAttributes>;
/** Ensures that the props do not include ref at all */
type PropsWithoutRef =
// Pick would not be sufficient for this. We'd like to avoid unnecessary mapping and need a distributive conditional to support unions.
// see: https://www.typescriptlang.org/docs/handbook/2/conditional-types.html#distributive-conditional-types
// https://github.com/Microsoft/TypeScript/issues/28339
P extends any ? ('ref' extends keyof P ? Pick
> : P) : P;
/** Ensures that the props do not include string ref, which cannot be forwarded */
type PropsWithRef
=
// Just "P extends { ref?: infer R }" looks sufficient, but R will infer as {} if P is {}.
'ref' extends keyof P
? P extends { ref?: infer R | undefined }
? string extends R
? PropsWithoutRef
& { ref?: Exclude | undefined }
: P
: P
: P;
type PropsWithChildren = P & { children?: ReactNode | undefined };
/**
* NOTE: prefer ComponentPropsWithRef, if the ref is forwarded,
* or ComponentPropsWithoutRef when refs are not supported.
*/
type ComponentProps> =
T extends JSXElementConstructor
? P
: T extends keyof JSX.IntrinsicElements
? JSX.IntrinsicElements[T]
: {};
type ComponentPropsWithRef =
T extends ComponentClass
? PropsWithoutRef & RefAttributes>
: PropsWithRef>;
type ComponentPropsWithoutRef =
PropsWithoutRef>;
type ComponentRef = T extends NamedExoticComponent<
ComponentPropsWithoutRef & RefAttributes
>
? Method
: ComponentPropsWithRef extends RefAttributes
? Method
: never;
// will show `Memo(${Component.displayName || Component.name})` in devtools by default,
// but can be given its own specific name
type MemoExoticComponent> = NamedExoticComponent> & {
readonly type: T;
};
function memo(
Component: FunctionComponent
,
propsAreEqual?: (prevProps: Readonly>, nextProps: Readonly>) => boolean
): NamedExoticComponent;
function memo>(
Component: T,
propsAreEqual?: (prevProps: Readonly>, nextProps: Readonly>) => boolean
): MemoExoticComponent;
type LazyExoticComponent> = ExoticComponent> & {
readonly _result: T;
};
function lazy>(
factory: () => Promise<{ default: T }>
): LazyExoticComponent;
//
// React Hooks
// ----------------------------------------------------------------------
// based on the code in https://github.com/facebook/react/pull/13968
// Unlike the class component setState, the updates are not allowed to be partial
type SetStateAction = S | ((prevState: S) => S);
// this technically does accept a second argument, but it's already under a deprecation warning
// and it's not even released so probably better to not define it.
type Dispatch = (value: A) => void;
// Since action _can_ be undefined, dispatch may be called without any parameters.
type DispatchWithoutAction = () => void;
// Unlike redux, the actions _can_ be anything
type Reducer = (prevState: S, action: A) => S;
// If useReducer accepts a reducer without action, dispatch may be called without any parameters.
type ReducerWithoutAction = (prevState: S) => S;
// types used to try and prevent the compiler from reducing S
// to a supertype common with the second argument to useReducer()
type ReducerState> = R extends Reducer ? S : never;
type ReducerAction> = R extends Reducer ? A : never;
// The identity check is done with the SameValue algorithm (Object.is), which is stricter than ===
type ReducerStateWithoutAction> =
R extends ReducerWithoutAction ? S : never;
// TODO (TypeScript 3.0): ReadonlyArray
type DependencyList = ReadonlyArray;
// NOTE: callbacks are _only_ allowed to return either void, or a destructor.
type EffectCallback = () => (void | Destructor);
interface MutableRefObject {
current: T;
}
// This will technically work if you give a Consumer or Provider but it's deprecated and warns
/**
* Accepts a context object (the value returned from `React.createContext`) and returns the current
* context value, as given by the nearest context provider for the given context.
*
* @version 16.8.0
* @see https://reactjs.org/docs/hooks-reference.html#usecontext
*/
function useContext(context: Context/*, (not public API) observedBits?: number|boolean */): T;
/**
* Returns a stateful value, and a function to update it.
*
* @version 16.8.0
* @see https://reactjs.org/docs/hooks-reference.html#usestate
*/
function useState(initialState: S | (() => S)): [S, Dispatch>];
// convenience overload when first argument is omitted
/**
* Returns a stateful value, and a function to update it.
*
* @version 16.8.0
* @see https://reactjs.org/docs/hooks-reference.html#usestate
*/
function useState(): [S | undefined, Dispatch>];
/**
* An alternative to `useState`.
*
* `useReducer` is usually preferable to `useState` when you have complex state logic that involves
* multiple sub-values. It also lets you optimize performance for components that trigger deep
* updates because you can pass `dispatch` down instead of callbacks.
*
* @version 16.8.0
* @see https://reactjs.org/docs/hooks-reference.html#usereducer
*/
// overload where dispatch could accept 0 arguments.
function useReducer, I>(
reducer: R,
initializerArg: I,
initializer: (arg: I) => ReducerStateWithoutAction
): [ReducerStateWithoutAction, DispatchWithoutAction];
/**
* An alternative to `useState`.
*
* `useReducer` is usually preferable to `useState` when you have complex state logic that involves
* multiple sub-values. It also lets you optimize performance for components that trigger deep
* updates because you can pass `dispatch` down instead of callbacks.
*
* @version 16.8.0
* @see https://reactjs.org/docs/hooks-reference.html#usereducer
*/
// overload where dispatch could accept 0 arguments.
function useReducer>(
reducer: R,
initializerArg: ReducerStateWithoutAction,
initializer?: undefined
): [ReducerStateWithoutAction, DispatchWithoutAction];
/**
* An alternative to `useState`.
*
* `useReducer` is usually preferable to `useState` when you have complex state logic that involves
* multiple sub-values. It also lets you optimize performance for components that trigger deep
* updates because you can pass `dispatch` down instead of callbacks.
*
* @version 16.8.0
* @see https://reactjs.org/docs/hooks-reference.html#usereducer
*/
// overload where "I" may be a subset of ReducerState; used to provide autocompletion.
// If "I" matches ReducerState exactly then the last overload will allow initializer to be omitted.
// the last overload effectively behaves as if the identity function (x => x) is the initializer.
function useReducer, I>(
reducer: R,
initializerArg: I & ReducerState,
initializer: (arg: I & ReducerState) => ReducerState
): [ReducerState, Dispatch>];
/**
* An alternative to `useState`.
*
* `useReducer` is usually preferable to `useState` when you have complex state logic that involves
* multiple sub-values. It also lets you optimize performance for components that trigger deep
* updates because you can pass `dispatch` down instead of callbacks.
*
* @version 16.8.0
* @see https://reactjs.org/docs/hooks-reference.html#usereducer
*/
// overload for free "I"; all goes as long as initializer converts it into "ReducerState".
function useReducer, I>(
reducer: R,
initializerArg: I,
initializer: (arg: I) => ReducerState
): [ReducerState, Dispatch>];
/**
* An alternative to `useState`.
*
* `useReducer` is usually preferable to `useState` when you have complex state logic that involves
* multiple sub-values. It also lets you optimize performance for components that trigger deep
* updates because you can pass `dispatch` down instead of callbacks.
*
* @version 16.8.0
* @see https://reactjs.org/docs/hooks-reference.html#usereducer
*/
// I'm not sure if I keep this 2-ary or if I make it (2,3)-ary; it's currently (2,3)-ary.
// The Flow types do have an overload for 3-ary invocation with undefined initializer.
// NOTE: without the ReducerState indirection, TypeScript would reduce S to be the most common
// supertype between the reducer's return type and the initialState (or the initializer's return type),
// which would prevent autocompletion from ever working.
// TODO: double-check if this weird overload logic is necessary. It is possible it's either a bug
// in older versions, or a regression in newer versions of the typescript completion service.
function useReducer>(
reducer: R,
initialState: ReducerState,
initializer?: undefined
): [ReducerState, Dispatch>];
/**
* `useRef` returns a mutable ref object whose `.current` property is initialized to the passed argument
* (`initialValue`). The returned object will persist for the full lifetime of the component.
*
* Note that `useRef()` is useful for more than the `ref` attribute. It’s handy for keeping any mutable
* value around similar to how you’d use instance fields in classes.
*
* @version 16.8.0
* @see https://reactjs.org/docs/hooks-reference.html#useref
*/
function useRef(initialValue: T): MutableRefObject;
// convenience overload for refs given as a ref prop as they typically start with a null value
/**
* `useRef` returns a mutable ref object whose `.current` property is initialized to the passed argument
* (`initialValue`). The returned object will persist for the full lifetime of the component.
*
* Note that `useRef()` is useful for more than the `ref` attribute. It’s handy for keeping any mutable
* value around similar to how you’d use instance fields in classes.
*
* Usage note: if you need the result of useRef to be directly mutable, include `| null` in the type
* of the generic argument.
*
* @version 16.8.0
* @see https://reactjs.org/docs/hooks-reference.html#useref
*/
function useRef(initialValue: T|null): RefObject;
// convenience overload for potentially undefined initialValue / call with 0 arguments
// has a default to stop it from defaulting to {} instead
/**
* `useRef` returns a mutable ref object whose `.current` property is initialized to the passed argument
* (`initialValue`). The returned object will persist for the full lifetime of the component.
*
* Note that `useRef()` is useful for more than the `ref` attribute. It’s handy for keeping any mutable
* value around similar to how you’d use instance fields in classes.
*
* @version 16.8.0
* @see https://reactjs.org/docs/hooks-reference.html#useref
*/
function useRef(): MutableRefObject;
/**
* The signature is identical to `useEffect`, but it fires synchronously after all DOM mutations.
* Use this to read layout from the DOM and synchronously re-render. Updates scheduled inside
* `useLayoutEffect` will be flushed synchronously, before the browser has a chance to paint.
*
* Prefer the standard `useEffect` when possible to avoid blocking visual updates.
*
* If you’re migrating code from a class component, `useLayoutEffect` fires in the same phase as
* `componentDidMount` and `componentDidUpdate`.
*
* @version 16.8.0
* @see https://reactjs.org/docs/hooks-reference.html#uselayouteffect
*/
function useLayoutEffect(effect: EffectCallback, deps?: DependencyList): void;
/**
* Accepts a function that contains imperative, possibly effectful code.
*
* @param effect Imperative function that can return a cleanup function
* @param deps If present, effect will only activate if the values in the list change.
*
* @version 16.8.0
* @see https://reactjs.org/docs/hooks-reference.html#useeffect
*/
function useEffect(effect: EffectCallback, deps?: DependencyList): void;
// NOTE: this does not accept strings, but this will have to be fixed by removing strings from type Ref
/**
* `useImperativeHandle` customizes the instance value that is exposed to parent components when using
* `ref`. As always, imperative code using refs should be avoided in most cases.
*
* `useImperativeHandle` should be used with `React.forwardRef`.
*
* @version 16.8.0
* @see https://reactjs.org/docs/hooks-reference.html#useimperativehandle
*/
function useImperativeHandle(ref: Ref