Merge pull request #8543 from Asana/react

[React] Use intersection types for key/ref; preserve instance type T on element types
This commit is contained in:
Masahiro Wakame
2016-03-16 00:47:21 +09:00
14 changed files with 434 additions and 258 deletions
+1 -4
View File
@@ -387,16 +387,13 @@ declare module FixedDataTable {
}
export class Table extends __React.Component<TableProps, {}> {
render(): __React.DOMElement<any>
}
export class Column extends __React.Component<ColumnProps, {}> {
render(): __React.DOMElement<any>
}
export class ColumnGroup extends __React.Component<ColumnGroupProps, {}> {
render(): __React.DOMElement<any>
}
}
declare module "fixed-data-table" {
export = FixedDataTable;
}
}
-4
View File
@@ -483,16 +483,12 @@ declare module FixedDataTable {
}
export class Table extends __React.Component<TableProps, {}> {
render(): __React.DOMElement<any>
}
export class Column extends __React.Component<ColumnProps, {}> {
render(): __React.DOMElement<any>
}
export class ColumnGroup extends __React.Component<ColumnGroupProps, {}> {
render(): __React.DOMElement<any>
}
export class Cell extends __React.Component<CellProps, {}> {
render(): __React.DOMElement<any>
}
}
+1 -1
View File
@@ -19,7 +19,7 @@ var clickHandler: React.MouseEventHandler
// Tests with spec string
function spec_string () {
var result: React.ReactHTMLElement
var result: React.ReactHTMLElement<HTMLElement>
// just spec string
result = $('div')
+2 -2
View File
@@ -31,7 +31,7 @@ declare module 'jsnox' {
* @param children A single React node (string or ReactElement) or array of nodes.
* Note that unlike with React itself, multiple children must be placed into an array.
*/
<P>(specString: string, children: React.ReactNode): React.DOMElement<P>
<P>(specString: string, children: React.ReactNode): React.DOMElement<P, Element>
/**
* Renders an HTML element from the given spec string, with optional props
@@ -42,7 +42,7 @@ declare module 'jsnox' {
* @param children A single React node (string or ReactElement) or array of nodes.
* Note that unlike with React itself, multiple children must be placed into an array.
*/
<P>(specString: string, props?: React.HTMLAttributes, children?: React.ReactNode): React.DOMElement<P>
<P>(specString: string, props?: React.HTMLAttributes, children?: React.ReactNode): React.DOMElement<P, Element>
/**
+1 -1
View File
@@ -262,7 +262,7 @@ module Board {
};
render() {
var squares: React.DOMElement<React.HTMLAttributes>[] = [];
var squares: React.ReactHTMLElement<HTMLDivElement>[] = [];
for (let i = 0; i < 64; i++) {
squares.push(this._renderSquare(i));
}
+1 -1
View File
@@ -9,7 +9,7 @@ declare module "react-holder" {
import React = __React;
interface ReactHolderProp extends React.HTMLProps<ReactHolder> {
interface ReactHolderProp extends React.HTMLAttributes {
width: string | number;
height: string | number;
updateOnResize: boolean;
-1
View File
@@ -76,7 +76,6 @@ declare module reactInputCalendar {
}
interface ReactInputCalendarState { }
export class ReactInputCalendar extends __React.Component<ReactInputCalendarProps, ReactInputCalendarState> {
render(): __React.DOMElement<any>;
}
}
declare var ReactInputCalendar: typeof reactInputCalendar.ReactInputCalendar
-1
View File
@@ -113,7 +113,6 @@ declare module rswf {
flashvars?: Object | string
}
export class ReactSWF extends __React.Component<Props, State>{
render(): __React.DOMElement<any>
/**
* Returns the Flash Player object DOM node.
* Should be prefered over `React.findDOMNode`.
+79 -3
View File
@@ -1,5 +1,81 @@
# React v0.14.2 Type Definitions
# React v0.14.4 Type Definitions
If you are using modules you should use `react.d.ts`, `react-dom.d.ts` and any of the `react-addon-*.d.ts` definition files.
This directory contains type definitions for the following React packages:
- `react`
- `react-addons-create-fragment`
- `react-addons-css-transition-group`
- `react-addons-linked-state-mixin`
- `react-addons-perf`
- `react-addons-pure-render-mixin`
- `react-addons-shallow-compare`
- `react-addons-test-utils`
- `react-addons-transition-group`
- `react-addons-update`
- `react-dom`
If you are using the global `React` variable, you should use `react-global.d.ts`.
## Getting Started
If you are using modules you should use `react.d.ts`, `react-dom.d.ts` or any of the `react-addons-*.d.ts` definition files. If `React` is in your global namespace, you should use `react-global.d.ts`.
## Known Problems & Workarounds
### **The type of `setState` is incorrect.**
The `setState(state)` method on `React.Component<P, S>` takes an object with a subset of the properties on `S`, but there's no way to express this in TypeScript currently. The workaround is simple: make all properties on `S` optional. There are a number of [proposals](https://github.com/Microsoft/TypeScript/issues/2710) on [ways](https://github.com/Microsoft/TypeScript/issues/4889) to [solve](https://github.com/Microsoft/TypeScript/issues/7355) this problem, but nothing seems to have been approved yet.
### **The type of `cloneElement` is incorrect.**
This is similar to the `setState` problem, in that `cloneElement(element, props)` should should accept a `props` object with a subset of the properties on `element.props`. There is an additional complication, however—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
```ts
declare function cloneElement<P extends Q, Q>(
element: ReactElement<P>,
props?: Q & Attributes,
...children: ReactNode[]): ReactElement<P>;
```
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:
```ts
interface ButtonProps {
label: string,
isDisabled?: boolean;
}
var element: React.CElement<ButtonProps, Button>;
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, <React.ClassAttributes<Button>>{ ref: button => button.reset() });
React.cloneElement(element, <{ isDisabled?: boolean } & React.Attributes>{
key: "disabledButton",
isDisabled: true
});
```
### **`React.Component<P, S>` subclass members aren't contextually typed.**
This problem manifests itself in two ways. It should be fixed in [TypeScript 2.0](https://github.com/Microsoft/TypeScript/pull/6118).
- You might expect `componentDidUpdate(prevProps, prevState)` to have `prevProps` and `prevState` contextually typed as `P` and `S` respectively, but currently that is not the case. You must explicitly type-annotate both arguments.
- You may get a cryptic error message when either `React.createElement` or `React.createFactory` doesn't recognize the `type` argument that you passed in as a valid `React.Component` subclass, because you overrode one of the static or instance members with a type that's not compatible with the superclass property's type. For example, with the following code:
```ts
import * as React from "react";
class MyComponent extends React.Component<Props, {}> {
static contextTypes = {
someValue: React.PropTypes.string
};
}
React.createFactory(MyComponent);
```
you might get this error:
```
error TS2345: Argument of type 'typeof MyComponent' is not assignable to parameter of type 'string | ComponentClass<Props> | StatelessComponent<Props>'
Type 'typeof ModernComponent' is not assignable to type 'StatelessComponent<Props>'.
Types of property 'contextTypes' are incompatible.
Type '{ someValue: Requireable<any>; }' is not assignable to type 'ValidationMap<any>'.
Index signature is missing in type '{ someValue: Requireable<any>; }'.
```
The work around is to add an explicit type annotation:
```ts
static contextTypes: React.ValidationMap<any> = ...
```
+23 -15
View File
@@ -94,23 +94,31 @@ declare namespace __React {
export var wheel: EventSimulator;
}
export function renderIntoDocument<T extends Element>(
element: DOMElement<any, T>): T;
export function renderIntoDocument(
element: DOMElement<any>): Element;
element: SFCElement<any>): void;
export function renderIntoDocument<T extends Component<any, any>>(
element: CElement<any, T>): T;
export function renderIntoDocument<P>(
element: ReactElement<P>): Component<P, any>;
export function renderIntoDocument<C extends Component<any, any>>(
element: ReactElement<any>): C;
element: ReactElement<P>): Component<P, {}> | Element | void;
export function mockComponent(
mocked: MockedComponentClass, mockTagName?: string): typeof TestUtils;
export function isElementOfType(
element: ReactElement<any>, type: ReactType): boolean;
export function isDOMComponent(instance: ReactInstance): boolean;
export function isCompositeComponent(instance: ReactInstance): boolean;
export function isCompositeComponentWithType(
instance: ReactInstance,
type: ComponentClass<any>): boolean;
export function isElementOfType<T extends HTMLElement>(
element: ReactElement<any>, type: string): element is ReactHTMLElement<T>;
export function isElementOfType<P extends DOMAttributes, T extends Element>(
element: ReactElement<any>, type: string): element is DOMElement<P, T>;
export function isElementOfType<P>(
element: ReactElement<any>, type: SFC<P>): element is SFCElement<P>;
export function isElementOfType<P, T extends Component<P, {}>, C extends ComponentClass<P>>(
element: ReactElement<any>, type: ClassType<P, T, C>): element is CElement<P, T>;
export function isDOMComponent(instance: ReactInstance): instance is Element;
export function isCompositeComponent(instance: ReactInstance): instance is Component<any, any>;
export function isCompositeComponentWithType<T extends Component<any, any>, C extends ComponentClass<any>>(
instance: ReactInstance, type: ClassType<any, T, C>): T;
export function findAllInRenderedTree(
root: Component<any, any>,
@@ -130,13 +138,13 @@ declare namespace __React {
root: Component<any, any>,
tagName: string): Element;
export function scryRenderedComponentsWithType<T extends Component<{}, {}>>(
export function scryRenderedComponentsWithType<T extends Component<{}, {}>, C extends ComponentClass<{}>>(
root: Component<any, any>,
type: { new(): T }): T[];
type: ClassType<any, T, C>): T[];
export function findRenderedComponentWithType<T extends Component<{}, {}>>(
export function findRenderedComponentWithType<T extends Component<{}, {}>, C extends ComponentClass<{}>>(
root: Component<any, any>,
type: { new(): T }): T;
type: ClassType<any, T, C>): T;
export function createRenderer(): ShallowRenderer;
}
+28 -19
View File
@@ -10,18 +10,22 @@ declare namespace __React {
function findDOMNode<E extends Element>(instance: ReactInstance): E;
function findDOMNode(instance: ReactInstance): Element;
function render<P extends DOMAttributes, T extends Element>(
element: DOMElement<P, T>,
container: Element,
callback?: (element: T) => any): T;
function render<P>(
element: DOMElement<P>,
element: SFCElement<P>,
container: Element,
callback?: (element: Element) => any): Element;
function render<P, S>(
element: ClassicElement<P>,
callback?: () => any): void;
function render<P, T extends Component<P, {}>>(
element: CElement<P, T>,
container: Element,
callback?: (component: ClassicComponent<P, S>) => any): ClassicComponent<P, S>;
function render<P, S>(
callback?: (component: T) => any): T;
function render<P>(
element: ReactElement<P>,
container: Element,
callback?: (component: Component<P, S>) => any): Component<P, S>;
callback?: (component?: Component<P, {}> | Element) => any): Component<P, {}> | Element | void;
function unmountComponentAtNode(container: Element): boolean;
@@ -31,21 +35,26 @@ declare namespace __React {
function unstable_batchedUpdates<A>(callback: (a: A) => any, a: A): void;
function unstable_batchedUpdates(callback: () => any): void;
function unstable_renderSubtreeIntoContainer<P extends DOMAttributes, T extends Element>(
parentComponent: Component<any, any>,
element: DOMElement<P, T>,
container: Element,
callback?: (element: T) => any): T;
function unstable_renderSubtreeIntoContainer<P, T extends Component<P, {}>>(
parentComponent: Component<any, any>,
element: CElement<P, T>,
container: Element,
callback?: (component: T) => any): T;
function render<P>(
parentComponent: Component<any, any>,
element: SFCElement<P>,
container: Element,
callback?: () => any): void;
function unstable_renderSubtreeIntoContainer<P>(
parentComponent: Component<any, any>,
nextElement: DOMElement<P>,
element: ReactElement<P>,
container: Element,
callback?: (element: Element) => any): Element;
function unstable_renderSubtreeIntoContainer<P, S>(
parentComponent: Component<any, any>,
nextElement: ClassicElement<P>,
container: Element,
callback?: (component: ClassicComponent<P, S>) => any): ClassicComponent<P, S>;
function unstable_renderSubtreeIntoContainer<P, S>(
parentComponent: Component<any, any>,
nextElement: ReactElement<P>,
container: Element,
callback?: (component: Component<P, S>) => any): Component<P, S>;
callback?: (component?: Component<P, {}> | Element) => any): Component<P, {}> | Element | void;
}
namespace __DOMServer {
+10 -10
View File
@@ -1,6 +1,6 @@
/// <reference path="react-global.d.ts" />
interface Props extends React.Props<MyComponent> {
interface Props {
hello: string;
world?: string;
foo: number;
@@ -24,7 +24,7 @@ interface MyComponent extends React.Component<Props, State> {
reset(): void;
}
var props: Props = {
var props: Props & React.ClassAttributes<{}> = {
key: 42,
ref: "myComponent42",
hello: "world",
@@ -115,9 +115,9 @@ class ModernComponent extends React.Component<Props, State>
}
// React.createFactory
var factory: React.Factory<Props> =
var factory: React.CFactory<Props, ModernComponent> =
React.createFactory(ModernComponent);
var factoryElement: React.ReactElement<Props> =
var factoryElement: React.CElement<Props, ModernComponent> =
factory(props);
var classicFactory: React.ClassicFactory<Props> =
@@ -125,25 +125,25 @@ var classicFactory: React.ClassicFactory<Props> =
var classicFactoryElement: React.ClassicElement<Props> =
classicFactory(props);
var domFactory: React.DOMFactory<any> =
var domFactory: React.DOMFactory<React.DOMAttributes, Element> =
React.createFactory("foo");
var domFactoryElement: React.DOMElement<any> =
var domFactoryElement: React.DOMElement<React.DOMAttributes, Element> =
domFactory();
// React.createElement
var element: React.ReactElement<Props> =
var element: React.CElement<Props, ModernComponent> =
React.createElement(ModernComponent, props);
var classicElement: React.ClassicElement<Props> =
React.createElement(ClassicComponent, props);
var domElement: React.ReactHTMLElement =
var domElement: React.ReactHTMLElement<HTMLDivElement> =
React.createElement("div");
// React.cloneElement
var clonedElement: React.ReactElement<Props> =
var clonedElement: React.CElement<Props, ModernComponent> =
React.cloneElement(element, props);
var clonedClassicElement: React.ClassicElement<Props> =
React.cloneElement(classicElement, props);
var clonedDOMElement: React.ReactHTMLElement =
var clonedDOMElement: React.ReactHTMLElement<HTMLDivElement> =
React.cloneElement(domElement);
// React.render
+54 -26
View File
@@ -23,7 +23,7 @@ import TestUtils = require("react-addons-test-utils");
import TransitionGroup = require("react-addons-transition-group");
import update = require("react-addons-update");
interface Props extends React.Props<MyComponent> {
interface Props {
hello: string;
world?: string;
foo: number;
@@ -46,7 +46,7 @@ interface MyComponent extends React.Component<Props, State> {
reset(): void;
}
var props: Props = {
var props: Props & React.ClassAttributes<{}> = {
key: 42,
ref: "myComponent42",
hello: "world",
@@ -138,31 +138,35 @@ class ModernComponent extends React.Component<Props, State>
}
}
interface SCProps extends React.Props<{}> {
interface SCProps {
foo?: number;
}
var StatelessComponent = (props: SCProps) => {
function StatelessComponent(props: SCProps) {
return React.DOM.div(null, props.foo);
};
namespace StatelessComponent {
export var displayName = "StatelessComponent";
export var defaultProps = { foo: 42 };
}
// Must explicitly type-annotate to add displayName/defaultProps/contextTypes
var StatelessComponent2: React.StatelessComponent<SCProps> =
(props: SCProps) => React.DOM.div(null, props.foo);
var StatelessComponent2: React.SFC<SCProps> =
// props is contextually typed
props => React.DOM.div(null, props.foo);
StatelessComponent2.displayName = "StatelessComponent2";
StatelessComponent2.defaultProps = {
foo: 42
};
// React.createFactory
var factory: React.Factory<Props> =
var factory: React.CFactory<Props, ModernComponent> =
React.createFactory(ModernComponent);
var factoryElement: React.ReactElement<Props> =
var factoryElement: React.CElement<Props, ModernComponent> =
factory(props);
var statelessFactory: React.Factory<SCProps> =
var statelessFactory: React.SFCFactory<SCProps> =
React.createFactory(StatelessComponent);
var statelessElement: React.ReactElement<SCProps> =
var statelessElement: React.SFCElement<SCProps> =
statelessFactory(props);
var classicFactory: React.ClassicFactory<Props> =
@@ -170,37 +174,47 @@ var classicFactory: React.ClassicFactory<Props> =
var classicFactoryElement: React.ClassicElement<Props> =
classicFactory(props);
var domFactory: React.DOMFactory<any> =
var domFactory: React.DOMFactory<React.DOMAttributes, Element> =
React.createFactory("foo");
var domFactoryElement: React.DOMElement<any> =
var domFactoryElement: React.DOMElement<React.DOMAttributes, Element> =
domFactory();
// React.createElement
var element: React.ReactElement<Props> =
var element: React.CElement<Props, ModernComponent> =
React.createElement(ModernComponent, props);
var statelessElement: React.ReactElement<SCProps> =
var statelessElement: React.SFCElement<SCProps> =
React.createElement(StatelessComponent, props);
var classicElement: React.ClassicElement<Props> =
React.createElement(ClassicComponent, props);
var domElement: React.ReactHTMLElement =
var domElement: React.ReactHTMLElement<HTMLDivElement> =
React.createElement("div");
// React.cloneElement
var clonedElement: React.ReactElement<Props> =
var clonedElement: React.CElement<Props, ModernComponent> =
React.cloneElement(element, { foo: 43 });
var clonedStatelessElement: React.ReactElement<SCProps> =
var clonedElement2: React.CElement<Props, ModernComponent> =
// known problem: cloning with key or ref requires cast
React.cloneElement(element, <React.ClassAttributes<ModernComponent>>{
ref: c => c.reset()
});
var clonedElement3: React.CElement<Props, ModernComponent> =
React.cloneElement(element, <{ foo: number } & React.Attributes>{
key: "8eac7",
foo: 55
});
var clonedStatelessElement: React.SFCElement<SCProps> =
// known problem: cloning with optional props don't work properly
// workaround: cast to actual props type
React.cloneElement(statelessElement, <SCProps>{ foo: 44 });
var clonedClassicElement: React.ClassicElement<Props> =
React.cloneElement(classicElement, props);
var clonedDOMElement: React.ReactHTMLElement =
var clonedDOMElement: React.ReactHTMLElement<HTMLDivElement> =
React.cloneElement(domElement, {
className: "clonedElement"
});
// React.render
var component: React.Component<Props, any> =
var component: ModernComponent =
ReactDOM.render(element, container);
var classicComponent: React.ClassicComponent<Props, any> =
ReactDOM.render(classicElement, container);
@@ -220,9 +234,12 @@ domNode = ReactDOM.findDOMNode(domNode);
// React Elements
// --------------------------------------------------------------------------
var type = element.type;
var type: React.ComponentClass<Props> = element.type;
var elementProps: Props = element.props;
var key = element.key;
var key: React.Key = element.key;
var t: React.ReactType;
var name = typeof t === "string" ? t : t.displayName;
//
// React Components
@@ -250,12 +267,9 @@ myComponent.reset();
//
// Refs
// NB: to infer the correct type for callback refs, your component's Props
// interface must extend React.Props<T> where T is your component type (or
// an interface that it implements).
// --------------------------------------------------------------------------
interface RCProps extends React.Props<RefComponent> {
interface RCProps {
}
class RefComponent extends React.Component<RCProps, {}> {
@@ -546,6 +560,20 @@ var foundComponent: ModernComponent = TestUtils.findRenderedComponentWithType(
var foundComponents: ModernComponent[] = TestUtils.scryRenderedComponentsWithType(
inst, ModernComponent);
// ReactTestUtils custom type guards
var emptyElement: React.ReactElement<{}>;
if (TestUtils.isElementOfType(emptyElement, StatelessComponent)) {
emptyElement.props.foo;
}
var anyInstance: Element | React.Component<any, any>;
if (TestUtils.isDOMComponent(anyInstance)) {
anyInstance.getAttribute("className");
} else if (TestUtils.isCompositeComponent(anyInstance)) {
anyInstance.props;
}
//
// TransitionGroup addon
// --------------------------------------------------------------------------
+234 -170
View File
@@ -10,32 +10,44 @@ declare namespace __React {
// ----------------------------------------------------------------------
type ReactType = string | ComponentClass<any> | StatelessComponent<any>;
type Key = string | number;
type Ref<T> = string | ((instance: T) => any);
interface ReactElement<P extends Props<any>> {
type: string | ComponentClass<P> | StatelessComponent<P>;
interface Attributes {
key?: Key;
}
interface ClassAttributes<T> extends Attributes {
ref?: Ref<T>;
}
interface ReactElement<P> {
type: string | ComponentClass<P> | SFC<P>;
props: P;
key: Key;
ref: Ref<Component<P, any> | Element>;
key?: Key;
}
interface ClassicElement<P> extends ReactElement<P> {
type: ClassicComponentClass<P>;
ref: Ref<ClassicComponent<P, any>>;
interface SFCElement<P> extends ReactElement<P> {
type: SFC<P>;
}
interface DOMElement<P extends Props<Element>> extends ReactElement<P> {
type CElement<P, T extends Component<P, {}>> = ComponentElement<P, T>;
interface ComponentElement<P, T extends Component<P, {}>> extends ReactElement<P> {
type: ComponentClass<P>;
ref?: Ref<T>;
}
type ClassicElement<P> = CElement<P, ClassicComponent<P, {}>>;
interface DOMElement<P extends DOMAttributes, T extends Element> extends ReactElement<P> {
type: string;
ref: Ref<Element>;
ref: Ref<T>;
}
interface ReactHTMLElement extends DOMElement<HTMLProps<HTMLElement>> {
ref: Ref<HTMLElement>;
interface ReactHTMLElement<T extends HTMLElement> extends DOMElement<HTMLAttributes, T> {
}
interface ReactSVGElement extends DOMElement<SVGProps> {
ref: Ref<SVGElement>;
interface ReactSVGElement extends DOMElement<SVGAttributes, SVGElement> {
}
//
@@ -43,19 +55,29 @@ declare namespace __React {
// ----------------------------------------------------------------------
interface Factory<P> {
(props?: P, ...children: ReactNode[]): ReactElement<P>;
(props?: P & Attributes, ...children: ReactNode[]): ReactElement<P>;
}
interface ClassicFactory<P> extends Factory<P> {
(props?: P, ...children: ReactNode[]): ClassicElement<P>;
interface SFCFactory<P> {
(props?: P & Attributes, ...children: ReactNode[]): SFCElement<P>;
}
interface DOMFactory<P extends Props<Element>> extends Factory<P> {
(props?: P, ...children: ReactNode[]): DOMElement<P>;
interface ComponentFactory<P, T extends Component<P, {}>> {
(props?: P & ClassAttributes<T>, ...children: ReactNode[]): CElement<P, T>;
}
type HTMLFactory = DOMFactory<HTMLProps<HTMLElement>>;
type SVGFactory = DOMFactory<SVGProps>;
type CFactory<P, T extends Component<P, {}>> = ComponentFactory<P, T>;
type ClassicFactory<P> = CFactory<P, ClassicComponent<P, {}>>;
interface DOMFactory<P extends DOMAttributes, T extends Element> {
(props?: P & ClassAttributes<T>, ...children: ReactNode[]): DOMElement<P, T>;
}
interface HTMLFactory<T extends HTMLElement> extends DOMFactory<HTMLAttributes, T> {
}
interface SVGFactory extends DOMFactory<SVGAttributes, SVGElement> {
}
//
// React Nodes
@@ -75,41 +97,54 @@ declare namespace __React {
function createClass<P, S>(spec: ComponentSpec<P, S>): ClassicComponentClass<P>;
function createFactory<P>(type: string): DOMFactory<P>;
function createFactory<P>(type: ClassicComponentClass<P>): ClassicFactory<P>;
function createFactory<P>(type: ComponentClass<P> | StatelessComponent<P>): Factory<P>;
function createFactory<P extends DOMAttributes, T extends Element>(
type: string): DOMFactory<P, T>;
function createFactory<P>(type: SFC<P>): SFCFactory<P>;
function createFactory<P>(
type: ClassType<P, ClassicComponent<P, {}>, ClassicComponentClass<P>>): CFactory<P, ClassicComponent<P, {}>>;
function createFactory<P, T extends Component<P, {}>, C extends ComponentClass<P>>(
type: ClassType<P, T, C>): CFactory<P, T>;
function createFactory<P>(type: ComponentClass<P> | SFC<P>): Factory<P>;
function createElement<P>(
function createElement<P extends DOMAttributes, T extends Element>(
type: string,
props?: P,
...children: ReactNode[]): DOMElement<P>;
props?: P & ClassAttributes<T>,
...children: ReactNode[]): DOMElement<P, T>;
function createElement<P>(
type: ClassicComponentClass<P>,
props?: P,
...children: ReactNode[]): ClassicElement<P>;
type: SFC<P>,
props?: P & Attributes,
...children: ReactNode[]): SFCElement<P>;
function createElement<P>(
type: ComponentClass<P> | StatelessComponent<P>,
props?: P,
type: ClassType<P, ClassicComponent<P, {}>, ClassicComponentClass<P>>,
props?: P & ClassAttributes<ClassicComponent<P, {}>>,
...children: ReactNode[]): CElement<P, ClassicComponent<P, {}>>;
function createElement<P, T extends Component<P, {}>, C extends ComponentClass<P>>(
type: ClassType<P, T, C>,
props?: P & ClassAttributes<T>,
...children: ReactNode[]): CElement<P, T>;
function createElement<P>(
type: ComponentClass<P> | SFC<P>,
props?: P & Attributes,
...children: ReactNode[]): ReactElement<P>;
function cloneElement(
element: ReactHTMLElement,
props?: HTMLProps<HTMLElement>,
...children: ReactNode[]): ReactHTMLElement;
function cloneElement(
element: ReactSVGElement,
props?: SVGProps,
...children: ReactNode[]): ReactSVGElement;
function cloneElement<P extends DOMAttributes, T extends Element>(
element: DOMElement<P, T>,
props?: P & ClassAttributes<T>,
...children: ReactNode[]): DOMElement<P, T>;
function cloneElement<P extends Q, Q>(
element: ClassicElement<P>,
props?: Q,
...children: ReactNode[]): ClassicElement<P>;
element: SFCElement<P>,
props?: Q, // should be Q & Attributes, but then Q is inferred as {}
...children: ReactNode[]): SFCElement<P>;
function cloneElement<P extends Q, Q, T extends Component<P, {}>>(
element: CElement<P, T>,
props?: Q, // should be Q & ClassAttributes<T>
...children: ReactNode[]): CElement<P, T>;
function cloneElement<P extends Q, Q>(
element: ReactElement<P>,
props?: Q,
props?: Q, // should be Q & Attributes
...children: ReactNode[]): ReactElement<P>;
function isValidElement(object: {}): boolean;
function isValidElement<P>(object: {}): object is ReactElement<P>;
var DOM: ReactDOM;
var PropTypes: ReactPropTypes;
@@ -128,7 +163,13 @@ declare namespace __React {
setState(state: S, callback?: () => any): void;
forceUpdate(callBack?: () => any): void;
render(): JSX.Element;
props: P;
// React.Props<T> 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 conditionallly
// on the existence of `children` in `P`, then we should remove this.
props: P & { children?: ReactNode };
state: S;
context: {};
refs: {
@@ -150,6 +191,7 @@ declare namespace __React {
// Class Interfaces
// ----------------------------------------------------------------------
type SFC<P> = StatelessComponent<P>;
interface StatelessComponent<P> {
(props?: P, context?: any): ReactElement<any>;
propTypes?: ValidationMap<P>;
@@ -159,19 +201,29 @@ declare namespace __React {
}
interface ComponentClass<P> {
new(props?: P, context?: any): Component<P, any>;
new(props?: P, context?: any): Component<P, {}>;
propTypes?: ValidationMap<P>;
contextTypes?: ValidationMap<any>;
childContextTypes?: ValidationMap<any>;
defaultProps?: P;
displayName?: string;
}
interface ClassicComponentClass<P> extends ComponentClass<P> {
new(props?: P, context?: any): ClassicComponent<P, any>;
new(props?: P, context?: any): ClassicComponent<P, {}>;
getDefaultProps?(): P;
displayName?: string;
}
/**
* 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<P, T extends Component<P, {}>, C extends ComponentClass<P>> =
C &
(new() => T) &
(new() => { props: P });
//
// Component Specs and Lifecycle
// ----------------------------------------------------------------------
@@ -325,19 +377,34 @@ declare namespace __React {
// 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<T>`:
*
* ```ts
* var b: Button;
* var props: ButtonProps & ClassAttributes<Button> = {
* ref: b => button = b, // ok!
* label: "I'm a Button"
* };
* ```
*/
interface Props<T> {
children?: ReactNode;
key?: Key;
ref?: Ref<T>;
}
interface HTMLProps<T> extends HTMLAttributes, Props<T> {
interface HTMLProps<T> extends HTMLAttributes, ClassAttributes<T> {
}
interface SVGProps extends SVGAttributes, Props<SVGElement> {
interface SVGProps extends SVGAttributes, ClassAttributes<SVGElement> {
}
interface DOMAttributes {
children?: ReactNode;
dangerouslySetInnerHTML?: {
__html: string;
};
@@ -1898,6 +1965,7 @@ declare namespace __React {
multiple?: boolean;
muted?: boolean;
name?: string;
nonce?: string;
noValidate?: boolean;
open?: boolean;
optimum?: number;
@@ -1909,6 +1977,7 @@ declare namespace __React {
readOnly?: boolean;
rel?: string;
required?: boolean;
reversed?: boolean;
role?: string;
rows?: number;
rowSpan?: number;
@@ -2033,119 +2102,119 @@ declare namespace __React {
interface ReactDOM {
// HTML
a: HTMLFactory;
abbr: HTMLFactory;
address: HTMLFactory;
area: HTMLFactory;
article: HTMLFactory;
aside: HTMLFactory;
audio: HTMLFactory;
b: HTMLFactory;
base: HTMLFactory;
bdi: HTMLFactory;
bdo: HTMLFactory;
big: HTMLFactory;
blockquote: HTMLFactory;
body: HTMLFactory;
br: HTMLFactory;
button: HTMLFactory;
canvas: HTMLFactory;
caption: HTMLFactory;
cite: HTMLFactory;
code: HTMLFactory;
col: HTMLFactory;
colgroup: HTMLFactory;
data: HTMLFactory;
datalist: HTMLFactory;
dd: HTMLFactory;
del: HTMLFactory;
details: HTMLFactory;
dfn: HTMLFactory;
dialog: HTMLFactory;
div: HTMLFactory;
dl: HTMLFactory;
dt: HTMLFactory;
em: HTMLFactory;
embed: HTMLFactory;
fieldset: HTMLFactory;
figcaption: HTMLFactory;
figure: HTMLFactory;
footer: HTMLFactory;
form: HTMLFactory;
h1: HTMLFactory;
h2: HTMLFactory;
h3: HTMLFactory;
h4: HTMLFactory;
h5: HTMLFactory;
h6: HTMLFactory;
head: HTMLFactory;
header: HTMLFactory;
hgroup: HTMLFactory;
hr: HTMLFactory;
html: HTMLFactory;
i: HTMLFactory;
iframe: HTMLFactory;
img: HTMLFactory;
input: HTMLFactory;
ins: HTMLFactory;
kbd: HTMLFactory;
keygen: HTMLFactory;
label: HTMLFactory;
legend: HTMLFactory;
li: HTMLFactory;
link: HTMLFactory;
main: HTMLFactory;
map: HTMLFactory;
mark: HTMLFactory;
menu: HTMLFactory;
menuitem: HTMLFactory;
meta: HTMLFactory;
meter: HTMLFactory;
nav: HTMLFactory;
noscript: HTMLFactory;
object: HTMLFactory;
ol: HTMLFactory;
optgroup: HTMLFactory;
option: HTMLFactory;
output: HTMLFactory;
p: HTMLFactory;
param: HTMLFactory;
picture: HTMLFactory;
pre: HTMLFactory;
progress: HTMLFactory;
q: HTMLFactory;
rp: HTMLFactory;
rt: HTMLFactory;
ruby: HTMLFactory;
s: HTMLFactory;
samp: HTMLFactory;
script: HTMLFactory;
section: HTMLFactory;
select: HTMLFactory;
small: HTMLFactory;
source: HTMLFactory;
span: HTMLFactory;
strong: HTMLFactory;
style: HTMLFactory;
sub: HTMLFactory;
summary: HTMLFactory;
sup: HTMLFactory;
table: HTMLFactory;
tbody: HTMLFactory;
td: HTMLFactory;
textarea: HTMLFactory;
tfoot: HTMLFactory;
th: HTMLFactory;
thead: HTMLFactory;
time: HTMLFactory;
title: HTMLFactory;
tr: HTMLFactory;
track: HTMLFactory;
u: HTMLFactory;
ul: HTMLFactory;
"var": HTMLFactory;
video: HTMLFactory;
wbr: HTMLFactory;
a: HTMLFactory<HTMLAnchorElement>;
abbr: HTMLFactory<HTMLElement>;
address: HTMLFactory<HTMLElement>;
area: HTMLFactory<HTMLAreaElement>;
article: HTMLFactory<HTMLElement>;
aside: HTMLFactory<HTMLElement>;
audio: HTMLFactory<HTMLAudioElement>;
b: HTMLFactory<HTMLElement>;
base: HTMLFactory<HTMLBaseElement>;
bdi: HTMLFactory<HTMLElement>;
bdo: HTMLFactory<HTMLElement>;
big: HTMLFactory<HTMLElement>;
blockquote: HTMLFactory<HTMLElement>;
body: HTMLFactory<HTMLBodyElement>;
br: HTMLFactory<HTMLBRElement>;
button: HTMLFactory<HTMLButtonElement>;
canvas: HTMLFactory<HTMLCanvasElement>;
caption: HTMLFactory<HTMLElement>;
cite: HTMLFactory<HTMLElement>;
code: HTMLFactory<HTMLElement>;
col: HTMLFactory<HTMLTableColElement>;
colgroup: HTMLFactory<HTMLTableColElement>;
data: HTMLFactory<HTMLElement>;
datalist: HTMLFactory<HTMLDataListElement>;
dd: HTMLFactory<HTMLElement>;
del: HTMLFactory<HTMLElement>;
details: HTMLFactory<HTMLElement>;
dfn: HTMLFactory<HTMLElement>;
dialog: HTMLFactory<HTMLElement>;
div: HTMLFactory<HTMLDivElement>;
dl: HTMLFactory<HTMLDListElement>;
dt: HTMLFactory<HTMLElement>;
em: HTMLFactory<HTMLElement>;
embed: HTMLFactory<HTMLEmbedElement>;
fieldset: HTMLFactory<HTMLFieldSetElement>;
figcaption: HTMLFactory<HTMLElement>;
figure: HTMLFactory<HTMLElement>;
footer: HTMLFactory<HTMLElement>;
form: HTMLFactory<HTMLFormElement>;
h1: HTMLFactory<HTMLHeadingElement>;
h2: HTMLFactory<HTMLHeadingElement>;
h3: HTMLFactory<HTMLHeadingElement>;
h4: HTMLFactory<HTMLHeadingElement>;
h5: HTMLFactory<HTMLHeadingElement>;
h6: HTMLFactory<HTMLHeadingElement>;
head: HTMLFactory<HTMLHeadElement>;
header: HTMLFactory<HTMLElement>;
hgroup: HTMLFactory<HTMLElement>;
hr: HTMLFactory<HTMLHRElement>;
html: HTMLFactory<HTMLHtmlElement>;
i: HTMLFactory<HTMLElement>;
iframe: HTMLFactory<HTMLIFrameElement>;
img: HTMLFactory<HTMLImageElement>;
input: HTMLFactory<HTMLInputElement>;
ins: HTMLFactory<HTMLModElement>;
kbd: HTMLFactory<HTMLElement>;
keygen: HTMLFactory<HTMLElement>;
label: HTMLFactory<HTMLLabelElement>;
legend: HTMLFactory<HTMLLegendElement>;
li: HTMLFactory<HTMLLIElement>;
link: HTMLFactory<HTMLLinkElement>;
main: HTMLFactory<HTMLElement>;
map: HTMLFactory<HTMLMapElement>;
mark: HTMLFactory<HTMLElement>;
menu: HTMLFactory<HTMLElement>;
menuitem: HTMLFactory<HTMLElement>;
meta: HTMLFactory<HTMLMetaElement>;
meter: HTMLFactory<HTMLElement>;
nav: HTMLFactory<HTMLElement>;
noscript: HTMLFactory<HTMLElement>;
object: HTMLFactory<HTMLObjectElement>;
ol: HTMLFactory<HTMLOListElement>;
optgroup: HTMLFactory<HTMLOptGroupElement>;
option: HTMLFactory<HTMLOptionElement>;
output: HTMLFactory<HTMLElement>;
p: HTMLFactory<HTMLParagraphElement>;
param: HTMLFactory<HTMLParamElement>;
picture: HTMLFactory<HTMLElement>;
pre: HTMLFactory<HTMLPreElement>;
progress: HTMLFactory<HTMLProgressElement>;
q: HTMLFactory<HTMLQuoteElement>;
rp: HTMLFactory<HTMLElement>;
rt: HTMLFactory<HTMLElement>;
ruby: HTMLFactory<HTMLElement>;
s: HTMLFactory<HTMLElement>;
samp: HTMLFactory<HTMLElement>;
script: HTMLFactory<HTMLElement>;
section: HTMLFactory<HTMLElement>;
select: HTMLFactory<HTMLSelectElement>;
small: HTMLFactory<HTMLElement>;
source: HTMLFactory<HTMLSourceElement>;
span: HTMLFactory<HTMLSpanElement>;
strong: HTMLFactory<HTMLElement>;
style: HTMLFactory<HTMLStyleElement>;
sub: HTMLFactory<HTMLElement>;
summary: HTMLFactory<HTMLElement>;
sup: HTMLFactory<HTMLElement>;
table: HTMLFactory<HTMLTableElement>;
tbody: HTMLFactory<HTMLTableSectionElement>;
td: HTMLFactory<HTMLTableDataCellElement>;
textarea: HTMLFactory<HTMLTextAreaElement>;
tfoot: HTMLFactory<HTMLTableSectionElement>;
th: HTMLFactory<HTMLTableHeaderCellElement>;
thead: HTMLFactory<HTMLTableSectionElement>;
time: HTMLFactory<HTMLElement>;
title: HTMLFactory<HTMLTitleElement>;
tr: HTMLFactory<HTMLTableRowElement>;
track: HTMLFactory<HTMLTrackElement>;
u: HTMLFactory<HTMLElement>;
ul: HTMLFactory<HTMLUListElement>;
"var": HTMLFactory<HTMLElement>;
video: HTMLFactory<HTMLVideoElement>;
wbr: HTMLFactory<HTMLElement>;
// SVG
svg: SVGFactory;
@@ -2256,13 +2325,8 @@ declare namespace JSX {
}
interface ElementAttributesProperty { props: {}; }
interface IntrinsicAttributes {
key?: React.Key;
}
interface IntrinsicClassAttributes<T> {
ref?: React.Ref<T>;
}
interface IntrinsicAttributes extends React.Attributes { }
interface IntrinsicClassAttributes<T> extends React.ClassAttributes<T> { }
interface IntrinsicElements {
// HTML