// 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 };
type VoidOrUndefinedOnly = void | { [UNDEFINED_VOID_ONLY]: never };
// eslint-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
;
type ComponentType
= ComponentClass
| FunctionComponent
;
type JSXElementConstructor
=
| ((
props: P,
/**
* @deprecated https://legacy.react/ts5.0js.org/docs/legacy-context.html#referencing-context-in-stateless-function-components
*/
deprecatedLegacyContext?: any,
) => ReactElement | null)
| (new (props: P) => Component);
interface RefObject {
readonly current: T | null;
}
// Bivariance hack for consistent unsoundness with RefObject
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 {
/**
* Allows getting a ref to the component instance.
* Once the component unmounts, React will set `ref.current` to `null` (or call the ref with `null` if you passed a callback ref).
* @see https://react.dev/learn/referencing-values-with-refs#refs-and-the-dom
*/
ref?: Ref | undefined;
}
interface ClassAttributes extends Attributes {
/**
* Allows getting a ref to the component instance.
* Once the component unmounts, React will set `ref.current` to `null` (or call the ref with `null` if you passed a callback ref).
* @see https://react.dev/learn/referencing-values-with-refs#refs-and-the-dom
*/
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> { }
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;
}
/**
* @deprecated - This type is not relevant when using React. Inline the type instead to make the intent clear.
*/
type ReactText = string | number;
/**
* @deprecated - This type is not relevant when using React. Inline the type instead to make the intent clear.
*/
type ReactChild = ReactElement | string | number;
/**
* @deprecated Use either `ReactNode[]` if you need an array or `Iterable` if its passed to a host component.
*/
interface ReactNodeArray extends ReadonlyArray {}
/**
* WARNING: Not related to `React.Fragment`.
* @deprecated - This type is not relevant when using React. Inline the type instead to make the intent clear.
*/
type ReactFragment = Iterable;
/**
* For internal usage only.
* Different release channels declare additional types of ReactNode this particular release channel accepts.
* App or library types should never augment this interface.
*/
interface DO_NOT_USE_OR_YOU_WILL_BE_FIRED_EXPERIMENTAL_REACT_NODES {}
type ReactNode =
| ReactElement
| string
| number
| Iterable
| ReactPortal
| boolean
| null
| undefined
| DO_NOT_USE_OR_YOU_WILL_BE_FIRED_EXPERIMENTAL_REACT_NODES[keyof DO_NOT_USE_OR_YOU_WILL_BE_FIRED_EXPERIMENTAL_REACT_NODES];
//
// 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
;
// Sync with `ReactChildren` until `ReactChildren` is removed.
const Children: {
map(children: C | ReadonlyArray, fn: (child: C, index: number) => T):
C extends null | undefined ? C : Array>;
forEach(children: C | ReadonlyArray, fn: (child: C, index: number) => void): void;
count(children: any): number;
only(children: C): C extends any[] ? never : C;
toArray(children: ReactNode | ReactNode[]): Array>;
};
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?: ReactNode;
}
const Suspense: ExoticComponent;
const version: string;
/**
* {@link https://react.dev/reference/react/Profiler#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://react.dev/reference/react/Component#static-contexttype
*/
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://react.dev/reference/react/Component#context
*/
context: unknown;
constructor(props: Readonly | P);
/**
* @deprecated
* @see https://legacy.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;
readonly props: Readonly
;
state: Readonly;
/**
* @deprecated
* https://legacy.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
// ----------------------------------------------------------------------
type FC = FunctionComponent
;
interface FunctionComponent
{
(props: P, context?: any): ReactElement | null;
propTypes?: WeakValidationMap | undefined;
contextTypes?: ValidationMap | undefined;
defaultProps?: Partial | undefined;
displayName?: string | undefined;
}
/**
* @deprecated - Equivalent with `React.FC`.
*/
type VFC
= VoidFunctionComponent
;
/**
* @deprecated - Equivalent with `React.FunctionComponent`.
*/
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: P, 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;
}
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://legacy.reactjs.org/blog/2018/03/27/update-on-async-rendering.html#initializing-state
* @see https://legacy.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://legacy.reactjs.org/blog/2018/03/27/update-on-async-rendering.html#initializing-state
* @see https://legacy.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://legacy.reactjs.org/blog/2018/03/27/update-on-async-rendering.html#updating-state-based-on-props
* @see https://legacy.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://legacy.reactjs.org/blog/2018/03/27/update-on-async-rendering.html#updating-state-based-on-props
* @see https://legacy.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://legacy.reactjs.org/blog/2018/03/27/update-on-async-rendering.html#reading-dom-properties-before-an-update
* @see https://legacy.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://legacy.reactjs.org/blog/2018/03/27/update-on-async-rendering.html#reading-dom-properties-before-an-update
* @see https://legacy.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 =
// Omit 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 ? Omit
: 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 (new (props: infer P) => Component)
? 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;
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://react.dev/reference/react/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://react.dev/reference/react/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://react.dev/reference/react/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://react.dev/reference/react/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://react.dev/reference/react/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://react.dev/reference/react/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://react.dev/reference/react/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://react.dev/reference/react/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://react.dev/reference/react/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://react.dev/reference/react/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://react.dev/reference/react/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://react.dev/reference/react/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://react.dev/reference/react/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://react.dev/reference/react/useImperativeHandle
*/
function useImperativeHandle(ref: Ref|undefined, init: () => R, deps?: DependencyList): void;
// I made 'inputs' required here and in useMemo as there's no point to memoizing without the memoization key
// useCallback(X) is identical to just using X, useMemo(() => Y) is identical to just using Y.
/**
* `useCallback` will return a memoized version of the callback that only changes if one of the `inputs`
* has changed.
*
* @version 16.8.0
* @see https://react.dev/reference/react/useCallback
*/
// A specific function type would not trigger implicit any.
// See https://github.com/DefinitelyTyped/DefinitelyTyped/issues/52873#issuecomment-845806435 for a comparison between `Function` and more specific types.
// tslint:disable-next-line ban-types
function useCallback(callback: T, deps: DependencyList): T;
/**
* `useMemo` will only recompute the memoized value when one of the `deps` has changed.
*
* @version 16.8.0
* @see https://react.dev/reference/react/useMemo
*/
// allow undefined, but don't make it optional as that is very likely a mistake
function useMemo(factory: () => T, deps: DependencyList | undefined): T;
/**
* `useDebugValue` can be used to display a label for custom hooks in React DevTools.
*
* NOTE: We don’t recommend adding debug values to every custom hook.
* It’s most valuable for custom hooks that are part of shared libraries.
*
* @version 16.8.0
* @see https://react.dev/reference/react/useDebugValue
*/
// the name of the custom hook is itself derived from the function name at runtime:
// it's just the function name without the "use" prefix.
function useDebugValue(value: T, format?: (value: T) => any): void;
// must be synchronous
export type TransitionFunction = () => VoidOrUndefinedOnly;
// strange definition to allow vscode to show documentation on the invocation
export interface TransitionStartFunction {
/**
* State updates caused inside the callback are allowed to be deferred.
*
* **If some state update causes a component to suspend, that state update should be wrapped in a transition.**
*
* @param callback A _synchronous_ function which causes state updates that can be deferred.
*/
(callback: TransitionFunction): void;
}
/**
* Returns a deferred version of the value that may “lag behind” it.
*
* This is commonly used to keep the interface responsive when you have something that renders immediately
* based on user input and something that needs to wait for a data fetch.
*
* A good example of this is a text input.
*
* @param value The value that is going to be deferred
*
* @see https://react.dev/reference/react/useDeferredValue
*/
export function useDeferredValue(value: T): T;
/**
* Allows components to avoid undesirable loading states by waiting for content to load
* before transitioning to the next screen. It also allows components to defer slower,
* data fetching updates until subsequent renders so that more crucial updates can be
* rendered immediately.
*
* The `useTransition` hook returns two values in an array.
*
* The first is a boolean, React’s way of informing us whether we’re waiting for the transition to finish.
* The second is a function that takes a callback. We can use it to tell React which state we want to defer.
*
* **If some state update causes a component to suspend, that state update should be wrapped in a transition.**`
*
* @see https://react.dev/reference/react/useTransition
*/
export function useTransition(): [boolean, TransitionStartFunction];
/**
* Similar to `useTransition` but allows uses where hooks are not available.
*
* @param callback A _synchronous_ function which causes state updates that can be deferred.
*/
export function startTransition(scope: TransitionFunction): void;
export function useId(): string;
/**
* @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.
*
* @see https://github.com/facebook/react/pull/21913
*/
export function useInsertionEffect(effect: EffectCallback, deps?: DependencyList): void;
/**
* @param subscribe
* @param getSnapshot
*
* @see https://github.com/reactwg/react-18/discussions/86
*/
// keep in sync with `useSyncExternalStore` from `use-sync-external-store`
export function useSyncExternalStore(
subscribe: (onStoreChange: () => void) => () => void,
getSnapshot: () => Snapshot,
getServerSnapshot?: () => Snapshot,
): Snapshot;
//
// Event System
// ----------------------------------------------------------------------
// TODO: change any to unknown when moving to TS v3
interface BaseSyntheticEvent {
nativeEvent: E;
currentTarget: C;
target: T;
bubbles: boolean;
cancelable: boolean;
defaultPrevented: boolean;
eventPhase: number;
isTrusted: boolean;
preventDefault(): void;
isDefaultPrevented(): boolean;
stopPropagation(): void;
isPropagationStopped(): boolean;
persist(): void;
timeStamp: number;
type: string;
}
/**
* currentTarget - a reference to the element on which the event listener is registered.
*
* target - a reference to the element from which the event was originally dispatched.
* This might be a child element to the element on which the event listener is registered.
* If you thought this should be `EventTarget & T`, see https://github.com/DefinitelyTyped/DefinitelyTyped/issues/11508#issuecomment-256045682
*/
interface SyntheticEvent extends BaseSyntheticEvent {}
interface ClipboardEvent extends SyntheticEvent {
clipboardData: DataTransfer;
}
interface CompositionEvent extends SyntheticEvent {
data: string;
}
interface DragEvent extends MouseEvent {
dataTransfer: DataTransfer;
}
interface PointerEvent extends MouseEvent {
pointerId: number;
pressure: number;
tangentialPressure: number;
tiltX: number;
tiltY: number;
twist: number;
width: number;
height: number;
pointerType: 'mouse' | 'pen' | 'touch';
isPrimary: boolean;
}
interface FocusEvent extends SyntheticEvent {
relatedTarget: (EventTarget & RelatedTarget) | null;
target: EventTarget & Target;
}
interface FormEvent extends SyntheticEvent {
}
interface InvalidEvent extends SyntheticEvent {
target: EventTarget & T;
}
interface ChangeEvent extends SyntheticEvent {
target: EventTarget & T;
}
export type ModifierKey = "Alt" | "AltGraph" | "CapsLock" | "Control" | "Fn" | "FnLock" | "Hyper" | "Meta" | "NumLock" | "ScrollLock" | "Shift" | "Super" | "Symbol" | "SymbolLock";
interface KeyboardEvent extends UIEvent {
altKey: boolean;
/** @deprecated */
charCode: number;
ctrlKey: boolean;
code: string;
/**
* See [DOM Level 3 Events spec](https://www.w3.org/TR/uievents-key/#keys-modifier). for a list of valid (case-sensitive) arguments to this method.
*/
getModifierState(key: ModifierKey): boolean;
/**
* See the [DOM Level 3 Events spec](https://www.w3.org/TR/uievents-key/#named-key-attribute-values). for possible values
*/
key: string;
/** @deprecated */
keyCode: number;
locale: string;
location: number;
metaKey: boolean;
repeat: boolean;
shiftKey: boolean;
/** @deprecated */
which: number;
}
interface MouseEvent extends UIEvent {
altKey: boolean;
button: number;
buttons: number;
clientX: number;
clientY: number;
ctrlKey: boolean;
/**
* See [DOM Level 3 Events spec](https://www.w3.org/TR/uievents-key/#keys-modifier). for a list of valid (case-sensitive) arguments to this method.
*/
getModifierState(key: ModifierKey): boolean;
metaKey: boolean;
movementX: number;
movementY: number;
pageX: number;
pageY: number;
relatedTarget: EventTarget | null;
screenX: number;
screenY: number;
shiftKey: boolean;
}
interface TouchEvent extends UIEvent {
altKey: boolean;
changedTouches: TouchList;
ctrlKey: boolean;
/**
* See [DOM Level 3 Events spec](https://www.w3.org/TR/uievents-key/#keys-modifier). for a list of valid (case-sensitive) arguments to this method.
*/
getModifierState(key: ModifierKey): boolean;
metaKey: boolean;
shiftKey: boolean;
targetTouches: TouchList;
touches: TouchList;
}
interface UIEvent