// Type definitions for React 16.0 // Project: http://facebook.github.io/react/ // Definitions by: Asana // AssureSign // Microsoft // John Reilly // Benoit Benezech // Patricio Zavolinsky // Digiguru // Eric Anderson // Albert Kurniawan // Tanguy Krotoff // Dovydas Navickas // Stéphane Goetz // Rich Seviora // Definitions: https://github.com/DefinitelyTyped/DefinitelyTyped // TypeScript Version: 2.3 /* Known Problems & Workarounds 1. The type of cloneElement is incorrect. cloneElement(element, props) should accept props object with a subset of properties on element.props. React attributes, such as key and ref, should also be accepted in props, but should not exist on element.props. The "correct" way to model this, then, is with: declare function cloneElement

( element: ReactElement

, props?: Q & Attributes, ...children: ReactNode[]): ReactElement

; However, type inference for Q defaults to {} when intersected with another type. (https://github.com/Microsoft/TypeScript/pull/5738#issuecomment-181904905) And since any object is assignable to {}, we would lose the type safety of the P extends Q constraint. Therefore, the type of props is left as Q, which should work for most cases. If you need to call cloneElement with key or ref, you'll need a type cast: interface ButtonProps { label: string, isDisabled?: boolean; } var element: React.CElement; React.cloneElement(element, { label: "label" }); // cloning with optional props requires a cast React.cloneElement(element, <{ isDisabled?: boolean }>{ isDisabled: true }); // cloning with key or ref requires a cast React.cloneElement(element, >{ ref: button => button.reset() }); React.cloneElement(element, <{ isDisabled?: boolean } & React.Attributes>{ key: "disabledButton", isDisabled: true }); */ 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 NativeTransitionEvent = TransitionEvent; type NativeUIEvent = UIEvent; type NativeWheelEvent = WheelEvent; // tslint:disable-next-line:export-just-namespace export = React; export as namespace React; declare namespace React { // // React Elements // ---------------------------------------------------------------------- type ReactType = string | ComponentType; type ComponentType

= ComponentClass

| StatelessComponent

; type Key = string | number; type Ref = string | ((instance: T | null) => any); // tslint:disable-next-line:interface-over-type-literal type ComponentState = {}; interface Attributes { key?: Key; } interface ClassAttributes extends Attributes { ref?: Ref; } interface ReactElement

{ type: string | ComponentClass

| SFC

; props: P; key: Key | null; } interface SFCElement

extends ReactElement

{ type: SFC

; } type CElement> = ComponentElement; interface ComponentElement> extends ReactElement

{ type: ComponentClass

; ref?: Ref; } type ClassicElement

= CElement>; // string fallback for custom web-components interface DOMElement

| SVGAttributes, T extends Element> extends ReactElement

{ type: string; ref: Ref; } // ReactHTML for ReactHTMLElement // tslint:disable-next-line:no-empty-interface 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; } // // Factories // ---------------------------------------------------------------------- type Factory

= (props?: Attributes & P, ...children: ReactNode[]) => ReactElement

; type SFCFactory

= (props?: Attributes & P, ...children: ReactNode[]) => SFCElement

; 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; // tslint:disable-next-line:no-empty-interface 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; // Should be Array but type aliases cannot be recursive type ReactFragment = {} | Array; type ReactNode = ReactChild | ReactFragment | boolean | null | undefined; // // Top Level API // ---------------------------------------------------------------------- function createClass(spec: ComponentSpec): ClassicComponentClass

; // 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: SFC

): SFCFactory

; 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, ...children: ReactNode[]): DetailedReactHTMLElement, HTMLInputElement>; function createElement

, T extends HTMLElement>( type: keyof ReactHTML, props?: ClassAttributes & P, ...children: ReactNode[]): DetailedReactHTMLElement; function createElement

, T extends SVGElement>( type: keyof ReactSVG, props?: ClassAttributes & P, ...children: ReactNode[]): ReactSVGElement; function createElement

, T extends Element>( type: string, props?: ClassAttributes & P, ...children: ReactNode[]): DOMElement; // Custom components function createElement

( type: SFC

, props?: Attributes & P, ...children: ReactNode[]): SFCElement

; function createElement

( type: ClassType, ClassicComponentClass

>, props?: ClassAttributes> & P, ...children: ReactNode[]): CElement>; function createElement, C extends ComponentClass

>( type: ClassType, props?: ClassAttributes & P, ...children: ReactNode[]): CElement; function createElement

( type: SFC

| ComponentClass

| string, props?: Attributes & P, ...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: SFCElement

, props?: Q, // should be Q & Attributes, but then Q is inferred as {} ...children: ReactNode[]): SFCElement

; function cloneElement

>( element: CElement, props?: Q, // should be Q & ClassAttributes ...children: ReactNode[]): CElement; function cloneElement

( element: ReactElement

, props?: Q, // should be Q & Attributes ...children: ReactNode[]): ReactElement

; function isValidElement

(object: {}): object is ReactElement

; const DOM: ReactDOM; const PropTypes: ReactPropTypes; const Children: ReactChildren; const version: string; // // Component API // ---------------------------------------------------------------------- type ReactInstance = Component | Element; // Base component for plain JS classes // tslint:disable-next-line:no-empty-interface interface Component

extends ComponentLifecycle { } class Component { constructor(props?: P, context?: any); // Disabling unified-signatures to have separate overloads. It's easier to understand this way. // tslint:disable:unified-signatures setState(f: (prevState: S, props: P) => Pick, callback?: () => any): void; setState(state: Pick, callback?: () => any): void; // tslint:enable:unified-signatures forceUpdate(callBack?: () => any): void; render(): JSX.Element | null | false; // 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. props: Readonly<{ children?: ReactNode }> & Readonly

; state: Readonly; context: any; refs: { [key: string]: ReactInstance }; } class PureComponent

extends Component { } interface ClassicComponent

extends Component { replaceState(nextState: S, callback?: () => any): void; isMounted(): boolean; getInitialState?(): S; } interface ChildContextProvider { getChildContext(): CC; } // // Class Interfaces // ---------------------------------------------------------------------- type SFC

= StatelessComponent

; interface StatelessComponent

{ (props: P & { children?: ReactNode }, context?: any): ReactElement | null; propTypes?: ValidationMap

; contextTypes?: ValidationMap; defaultProps?: Partial

; displayName?: string; } interface ComponentClass

{ new (props?: P, context?: any): Component; propTypes?: ValidationMap

; contextTypes?: ValidationMap; childContextTypes?: ValidationMap; defaultProps?: Partial

; displayName?: string; } 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) & (new (props?: P, context?: any) => { props: P }); // // Component Specs and Lifecycle // ---------------------------------------------------------------------- interface ComponentLifecycle { /** * Called immediately before mounting occurs, and before `Component#render`. * Avoid introducing any side-effects or subscriptions in this method. */ componentWillMount?(): void; /** * Called immediately after a compoment is mounted. Setting state here will trigger re-rendering. */ componentDidMount?(): 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. */ componentWillReceiveProps?(nextProps: Readonly

, nextContext: any): 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 rendering when new props or state is received. Not called for the initial render. * * Note: You cannot call `Component#setState` here. */ componentWillUpdate?(nextProps: Readonly

, nextState: Readonly, nextContext: any): void; /** * Called immediately after updating occurs. Not called for the initial render. */ componentDidUpdate?(prevProps: Readonly

, prevState: Readonly, prevContext: any): void; /** * 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; } interface Mixin extends ComponentLifecycle { mixins?: Array>; statics?: { [key: string]: any; }; displayName?: string; propTypes?: ValidationMap; contextTypes?: ValidationMap; childContextTypes?: ValidationMap; getDefaultProps?(): P; getInitialState?(): S; } interface ComponentSpec extends Mixin { render(): ReactElement | null; [propertyName: string]: any; } // // Event System // ---------------------------------------------------------------------- interface SyntheticEvent { bubbles: boolean; currentTarget: EventTarget & T; cancelable: boolean; defaultPrevented: boolean; eventPhase: number; isTrusted: boolean; nativeEvent: Event; preventDefault(): void; isDefaultPrevented(): boolean; stopPropagation(): void; isPropagationStopped(): boolean; persist(): void; // If you thought this should be `EventTarget & T`, see https://github.com/DefinitelyTyped/DefinitelyTyped/pull/12239 target: EventTarget; timeStamp: number; type: string; } interface ClipboardEvent extends SyntheticEvent { clipboardData: DataTransfer; nativeEvent: NativeClipboardEvent; } interface CompositionEvent extends SyntheticEvent { data: string; nativeEvent: NativeCompositionEvent; } interface DragEvent extends MouseEvent { dataTransfer: DataTransfer; nativeEvent: NativeDragEvent; } interface FocusEvent extends SyntheticEvent { nativeEvent: NativeFocusEvent; relatedTarget: EventTarget; } // tslint:disable-next-line:no-empty-interface interface FormEvent extends SyntheticEvent { } interface InvalidEvent extends SyntheticEvent { target: EventTarget & T; } interface ChangeEvent extends SyntheticEvent { target: EventTarget & T; } interface KeyboardEvent extends SyntheticEvent { altKey: boolean; charCode: number; ctrlKey: boolean; getModifierState(key: string): boolean; key: string; keyCode: number; locale: string; location: number; metaKey: boolean; nativeEvent: NativeKeyboardEvent; repeat: boolean; shiftKey: boolean; which: number; } interface MouseEvent extends SyntheticEvent { altKey: boolean; button: number; buttons: number; clientX: number; clientY: number; ctrlKey: boolean; getModifierState(key: string): boolean; metaKey: boolean; nativeEvent: NativeMouseEvent; pageX: number; pageY: number; relatedTarget: EventTarget; screenX: number; screenY: number; shiftKey: boolean; } interface TouchEvent extends SyntheticEvent { altKey: boolean; changedTouches: TouchList; ctrlKey: boolean; getModifierState(key: string): boolean; metaKey: boolean; nativeEvent: NativeTouchEvent; shiftKey: boolean; targetTouches: TouchList; touches: TouchList; } interface UIEvent extends SyntheticEvent { detail: number; nativeEvent: NativeUIEvent; view: AbstractView; } interface WheelEvent extends MouseEvent { deltaMode: number; deltaX: number; deltaY: number; deltaZ: number; nativeEvent: NativeWheelEvent; } interface AnimationEvent extends SyntheticEvent { animationName: string; elapsedTime: number; nativeEvent: NativeAnimationEvent; pseudoElement: string; } interface TransitionEvent extends SyntheticEvent { elapsedTime: number; nativeEvent: NativeTransitionEvent; propertyName: string; pseudoElement: string; } // // Event Handler Types // ---------------------------------------------------------------------- type EventHandler> = (event: E) => void; type ReactEventHandler = EventHandler>; type ClipboardEventHandler = EventHandler>; type CompositionEventHandler = EventHandler>; type DragEventHandler = EventHandler>; type FocusEventHandler = EventHandler>; type FormEventHandler = EventHandler>; type ChangeEventHandler = EventHandler>; type KeyboardEventHandler = EventHandler>; type MouseEventHandler = EventHandler>; type TouchEventHandler = EventHandler>; type UIEventHandler = EventHandler>; type WheelEventHandler = EventHandler>; type AnimationEventHandler = EventHandler>; type TransitionEventHandler = EventHandler>; // // Props / DOM Attributes // ---------------------------------------------------------------------- /** * @deprecated. This was used to allow clients to pass `ref` and `key` * to `createElement`, which is no longer necessary due to intersection * types. If you need to declare a props object before passing it to * `createElement` or a factory, use `ClassAttributes`: * * ```ts * var b: Button | null; * var props: ButtonProps & ClassAttributes