diff --git a/fixed-data-table/fixed-data-table-0.4.7.d.ts b/fixed-data-table/fixed-data-table-0.4.7.d.ts index 1dc22dc3d..f681e5ea5 100644 --- a/fixed-data-table/fixed-data-table-0.4.7.d.ts +++ b/fixed-data-table/fixed-data-table-0.4.7.d.ts @@ -387,16 +387,13 @@ declare module FixedDataTable { } export class Table extends __React.Component { - render(): __React.DOMElement } export class Column extends __React.Component { - render(): __React.DOMElement } export class ColumnGroup extends __React.Component { - render(): __React.DOMElement } } declare module "fixed-data-table" { export = FixedDataTable; -} \ No newline at end of file +} diff --git a/fixed-data-table/fixed-data-table.d.ts b/fixed-data-table/fixed-data-table.d.ts index 843eb458e..c561abf41 100644 --- a/fixed-data-table/fixed-data-table.d.ts +++ b/fixed-data-table/fixed-data-table.d.ts @@ -483,16 +483,12 @@ declare module FixedDataTable { } export class Table extends __React.Component { - render(): __React.DOMElement } export class Column extends __React.Component { - render(): __React.DOMElement } export class ColumnGroup extends __React.Component { - render(): __React.DOMElement } export class Cell extends __React.Component { - render(): __React.DOMElement } } diff --git a/jsnox/jsnox-tests.ts b/jsnox/jsnox-tests.ts index 33e58720e..c1203f089 100644 --- a/jsnox/jsnox-tests.ts +++ b/jsnox/jsnox-tests.ts @@ -19,7 +19,7 @@ var clickHandler: React.MouseEventHandler // Tests with spec string function spec_string () { - var result: React.ReactHTMLElement + var result: React.ReactHTMLElement // just spec string result = $('div') diff --git a/jsnox/jsnox.d.ts b/jsnox/jsnox.d.ts index 22291956d..68687f719 100644 --- a/jsnox/jsnox.d.ts +++ b/jsnox/jsnox.d.ts @@ -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. */ -

(specString: string, children: React.ReactNode): React.DOMElement

+

(specString: string, children: React.ReactNode): React.DOMElement /** * 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. */ -

(specString: string, props?: React.HTMLAttributes, children?: React.ReactNode): React.DOMElement

+

(specString: string, props?: React.HTMLAttributes, children?: React.ReactNode): React.DOMElement /** diff --git a/react-dnd/react-dnd-tests.ts b/react-dnd/react-dnd-tests.ts index 2c92b7b33..5be7832d5 100644 --- a/react-dnd/react-dnd-tests.ts +++ b/react-dnd/react-dnd-tests.ts @@ -262,7 +262,7 @@ module Board { }; render() { - var squares: React.DOMElement[] = []; + var squares: React.ReactHTMLElement[] = []; for (let i = 0; i < 64; i++) { squares.push(this._renderSquare(i)); } diff --git a/react-holder/react-holder.d.ts b/react-holder/react-holder.d.ts index f130239ad..b29cd0893 100644 --- a/react-holder/react-holder.d.ts +++ b/react-holder/react-holder.d.ts @@ -9,7 +9,7 @@ declare module "react-holder" { import React = __React; - interface ReactHolderProp extends React.HTMLProps { + interface ReactHolderProp extends React.HTMLAttributes { width: string | number; height: string | number; updateOnResize: boolean; diff --git a/react-input-calendar/react-input-calendar.d.ts b/react-input-calendar/react-input-calendar.d.ts index ec539382f..14b877c8d 100644 --- a/react-input-calendar/react-input-calendar.d.ts +++ b/react-input-calendar/react-input-calendar.d.ts @@ -76,7 +76,6 @@ declare module reactInputCalendar { } interface ReactInputCalendarState { } export class ReactInputCalendar extends __React.Component { - render(): __React.DOMElement; } } declare var ReactInputCalendar: typeof reactInputCalendar.ReactInputCalendar diff --git a/react-swf/react-swf.d.ts b/react-swf/react-swf.d.ts index 374ec876a..21921f8f9 100644 --- a/react-swf/react-swf.d.ts +++ b/react-swf/react-swf.d.ts @@ -113,7 +113,6 @@ declare module rswf { flashvars?: Object | string } export class ReactSWF extends __React.Component{ - render(): __React.DOMElement /** * Returns the Flash Player object DOM node. * Should be prefered over `React.findDOMNode`. diff --git a/react/README.md b/react/README.md index 8990e8a71..1adf43f60 100644 --- a/react/README.md +++ b/react/README.md @@ -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` 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

( + 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: +```ts +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 +}); +``` + +### **`React.Component` 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 { + 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 | StatelessComponent' + Type 'typeof ModernComponent' is not assignable to type 'StatelessComponent'. + Types of property 'contextTypes' are incompatible. + Type '{ someValue: Requireable; }' is not assignable to type 'ValidationMap'. + Index signature is missing in type '{ someValue: Requireable; }'. + ``` + The work around is to add an explicit type annotation: + ```ts + static contextTypes: React.ValidationMap = ... + ``` diff --git a/react/react-addons-test-utils.d.ts b/react/react-addons-test-utils.d.ts index d71976ef6..35df25102 100644 --- a/react/react-addons-test-utils.d.ts +++ b/react/react-addons-test-utils.d.ts @@ -94,23 +94,31 @@ declare namespace __React { export var wheel: EventSimulator; } + export function renderIntoDocument( + element: DOMElement): T; export function renderIntoDocument( - element: DOMElement): Element; + element: SFCElement): void; + export function renderIntoDocument>( + element: CElement): T; export function renderIntoDocument

( - element: ReactElement

): Component; - export function renderIntoDocument>( - element: ReactElement): C; + element: ReactElement

): Component | Element | void; export function mockComponent( mocked: MockedComponentClass, mockTagName?: string): typeof TestUtils; - export function isElementOfType( - element: ReactElement, type: ReactType): boolean; - export function isDOMComponent(instance: ReactInstance): boolean; - export function isCompositeComponent(instance: ReactInstance): boolean; - export function isCompositeComponentWithType( - instance: ReactInstance, - type: ComponentClass): boolean; + export function isElementOfType( + element: ReactElement, type: string): element is ReactHTMLElement; + export function isElementOfType

( + element: ReactElement, type: string): element is DOMElement; + export function isElementOfType

( + element: ReactElement, type: SFC

): element is SFCElement

; + export function isElementOfType, C extends ComponentClass

>( + element: ReactElement, type: ClassType): element is CElement; + + export function isDOMComponent(instance: ReactInstance): instance is Element; + export function isCompositeComponent(instance: ReactInstance): instance is Component; + export function isCompositeComponentWithType, C extends ComponentClass>( + instance: ReactInstance, type: ClassType): T; export function findAllInRenderedTree( root: Component, @@ -130,13 +138,13 @@ declare namespace __React { root: Component, tagName: string): Element; - export function scryRenderedComponentsWithType>( + export function scryRenderedComponentsWithType, C extends ComponentClass<{}>>( root: Component, - type: { new(): T }): T[]; + type: ClassType): T[]; - export function findRenderedComponentWithType>( + export function findRenderedComponentWithType, C extends ComponentClass<{}>>( root: Component, - type: { new(): T }): T; + type: ClassType): T; export function createRenderer(): ShallowRenderer; } diff --git a/react/react-dom.d.ts b/react/react-dom.d.ts index 80a0c604e..492b546d1 100644 --- a/react/react-dom.d.ts +++ b/react/react-dom.d.ts @@ -10,18 +10,22 @@ declare namespace __React { function findDOMNode(instance: ReactInstance): E; function findDOMNode(instance: ReactInstance): Element; + function render

( + element: DOMElement, + container: Element, + callback?: (element: T) => any): T; function render

( - element: DOMElement

, + element: SFCElement

, container: Element, - callback?: (element: Element) => any): Element; - function render( - element: ClassicElement

, + callback?: () => any): void; + function render>( + element: CElement, container: Element, - callback?: (component: ClassicComponent) => any): ClassicComponent; - function render( + callback?: (component: T) => any): T; + function render

( element: ReactElement

, container: Element, - callback?: (component: Component) => any): Component; + callback?: (component?: Component | Element) => any): Component | Element | void; function unmountComponentAtNode(container: Element): boolean; @@ -31,21 +35,26 @@ declare namespace __React { function unstable_batchedUpdates(callback: (a: A) => any, a: A): void; function unstable_batchedUpdates(callback: () => any): void; + function unstable_renderSubtreeIntoContainer

( + parentComponent: Component, + element: DOMElement, + container: Element, + callback?: (element: T) => any): T; + function unstable_renderSubtreeIntoContainer>( + parentComponent: Component, + element: CElement, + container: Element, + callback?: (component: T) => any): T; + function render

( + parentComponent: Component, + element: SFCElement

, + container: Element, + callback?: () => any): void; function unstable_renderSubtreeIntoContainer

( parentComponent: Component, - nextElement: DOMElement

, + element: ReactElement

, container: Element, - callback?: (element: Element) => any): Element; - function unstable_renderSubtreeIntoContainer( - parentComponent: Component, - nextElement: ClassicElement

, - container: Element, - callback?: (component: ClassicComponent) => any): ClassicComponent; - function unstable_renderSubtreeIntoContainer( - parentComponent: Component, - nextElement: ReactElement

, - container: Element, - callback?: (component: Component) => any): Component; + callback?: (component?: Component | Element) => any): Component | Element | void; } namespace __DOMServer { diff --git a/react/react-global-tests.ts b/react/react-global-tests.ts index ac8b85116..3aaf4b2c1 100644 --- a/react/react-global-tests.ts +++ b/react/react-global-tests.ts @@ -1,6 +1,6 @@ /// -interface Props extends React.Props { +interface Props { hello: string; world?: string; foo: number; @@ -24,7 +24,7 @@ interface MyComponent extends React.Component { 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 } // React.createFactory -var factory: React.Factory = +var factory: React.CFactory = React.createFactory(ModernComponent); -var factoryElement: React.ReactElement = +var factoryElement: React.CElement = factory(props); var classicFactory: React.ClassicFactory = @@ -125,25 +125,25 @@ var classicFactory: React.ClassicFactory = var classicFactoryElement: React.ClassicElement = classicFactory(props); -var domFactory: React.DOMFactory = +var domFactory: React.DOMFactory = React.createFactory("foo"); -var domFactoryElement: React.DOMElement = +var domFactoryElement: React.DOMElement = domFactory(); // React.createElement -var element: React.ReactElement = +var element: React.CElement = React.createElement(ModernComponent, props); var classicElement: React.ClassicElement = React.createElement(ClassicComponent, props); -var domElement: React.ReactHTMLElement = +var domElement: React.ReactHTMLElement = React.createElement("div"); // React.cloneElement -var clonedElement: React.ReactElement = +var clonedElement: React.CElement = React.cloneElement(element, props); var clonedClassicElement: React.ClassicElement = React.cloneElement(classicElement, props); -var clonedDOMElement: React.ReactHTMLElement = +var clonedDOMElement: React.ReactHTMLElement = React.cloneElement(domElement); // React.render diff --git a/react/react-tests.ts b/react/react-tests.ts index 9147194dc..e0d9bb7be 100644 --- a/react/react-tests.ts +++ b/react/react-tests.ts @@ -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 { +interface Props { hello: string; world?: string; foo: number; @@ -46,7 +46,7 @@ interface MyComponent extends React.Component { 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 } } -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 = - (props: SCProps) => React.DOM.div(null, props.foo); +var StatelessComponent2: React.SFC = + // props is contextually typed + props => React.DOM.div(null, props.foo); StatelessComponent2.displayName = "StatelessComponent2"; StatelessComponent2.defaultProps = { foo: 42 }; // React.createFactory -var factory: React.Factory = +var factory: React.CFactory = React.createFactory(ModernComponent); -var factoryElement: React.ReactElement = +var factoryElement: React.CElement = factory(props); -var statelessFactory: React.Factory = +var statelessFactory: React.SFCFactory = React.createFactory(StatelessComponent); -var statelessElement: React.ReactElement = +var statelessElement: React.SFCElement = statelessFactory(props); var classicFactory: React.ClassicFactory = @@ -170,37 +174,47 @@ var classicFactory: React.ClassicFactory = var classicFactoryElement: React.ClassicElement = classicFactory(props); -var domFactory: React.DOMFactory = +var domFactory: React.DOMFactory = React.createFactory("foo"); -var domFactoryElement: React.DOMElement = +var domFactoryElement: React.DOMElement = domFactory(); // React.createElement -var element: React.ReactElement = +var element: React.CElement = React.createElement(ModernComponent, props); -var statelessElement: React.ReactElement = +var statelessElement: React.SFCElement = React.createElement(StatelessComponent, props); var classicElement: React.ClassicElement = React.createElement(ClassicComponent, props); -var domElement: React.ReactHTMLElement = +var domElement: React.ReactHTMLElement = React.createElement("div"); // React.cloneElement -var clonedElement: React.ReactElement = +var clonedElement: React.CElement = React.cloneElement(element, { foo: 43 }); -var clonedStatelessElement: React.ReactElement = +var clonedElement2: React.CElement = + // known problem: cloning with key or ref requires cast + React.cloneElement(element, >{ + ref: c => c.reset() + }); +var clonedElement3: React.CElement = + React.cloneElement(element, <{ foo: number } & React.Attributes>{ + key: "8eac7", + foo: 55 + }); +var clonedStatelessElement: React.SFCElement = // known problem: cloning with optional props don't work properly // workaround: cast to actual props type React.cloneElement(statelessElement, { foo: 44 }); var clonedClassicElement: React.ClassicElement = React.cloneElement(classicElement, props); -var clonedDOMElement: React.ReactHTMLElement = +var clonedDOMElement: React.ReactHTMLElement = React.cloneElement(domElement, { className: "clonedElement" }); // React.render -var component: React.Component = +var component: ModernComponent = ReactDOM.render(element, container); var classicComponent: React.ClassicComponent = ReactDOM.render(classicElement, container); @@ -220,9 +234,12 @@ domNode = ReactDOM.findDOMNode(domNode); // React Elements // -------------------------------------------------------------------------- -var type = element.type; +var type: React.ComponentClass = 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 where T is your component type (or -// an interface that it implements). // -------------------------------------------------------------------------- -interface RCProps extends React.Props { +interface RCProps { } class RefComponent extends React.Component { @@ -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; +if (TestUtils.isDOMComponent(anyInstance)) { + anyInstance.getAttribute("className"); +} else if (TestUtils.isCompositeComponent(anyInstance)) { + anyInstance.props; +} + // // TransitionGroup addon // -------------------------------------------------------------------------- diff --git a/react/react.d.ts b/react/react.d.ts index f4369e4a1..22d7c16ca 100644 --- a/react/react.d.ts +++ b/react/react.d.ts @@ -10,32 +10,44 @@ declare namespace __React { // ---------------------------------------------------------------------- type ReactType = string | ComponentClass | StatelessComponent; + type Key = string | number; type Ref = string | ((instance: T) => any); - interface ReactElement

> { - type: string | ComponentClass

| StatelessComponent

; + interface Attributes { + key?: Key; + } + interface ClassAttributes extends Attributes { + ref?: Ref; + } + + interface ReactElement

{ + type: string | ComponentClass

| SFC

; props: P; - key: Key; - ref: Ref | Element>; + key?: Key; } - interface ClassicElement

extends ReactElement

{ - type: ClassicComponentClass

; - ref: Ref>; + interface SFCElement

extends ReactElement

{ + type: SFC

; } - interface DOMElement

> extends ReactElement

{ + type CElement> = ComponentElement; + interface ComponentElement> extends ReactElement

{ + type: ComponentClass

; + ref?: Ref; + } + + type ClassicElement

= CElement>; + + interface DOMElement

extends ReactElement

{ type: string; - ref: Ref; + ref: Ref; } - interface ReactHTMLElement extends DOMElement> { - ref: Ref; + interface ReactHTMLElement extends DOMElement { } - interface ReactSVGElement extends DOMElement { - ref: Ref; + interface ReactSVGElement extends DOMElement { } // @@ -43,19 +55,29 @@ declare namespace __React { // ---------------------------------------------------------------------- interface Factory

{ - (props?: P, ...children: ReactNode[]): ReactElement

; + (props?: P & Attributes, ...children: ReactNode[]): ReactElement

; } - interface ClassicFactory

extends Factory

{ - (props?: P, ...children: ReactNode[]): ClassicElement

; + interface SFCFactory

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

; } - interface DOMFactory

> extends Factory

{ - (props?: P, ...children: ReactNode[]): DOMElement

; + interface ComponentFactory> { + (props?: P & ClassAttributes, ...children: ReactNode[]): CElement; } - type HTMLFactory = DOMFactory>; - type SVGFactory = DOMFactory; + type CFactory> = ComponentFactory; + type ClassicFactory

= CFactory>; + + interface DOMFactory

{ + (props?: P & ClassAttributes, ...children: ReactNode[]): DOMElement; + } + + interface HTMLFactory extends DOMFactory { + } + + interface SVGFactory extends DOMFactory { + } // // React Nodes @@ -75,41 +97,54 @@ declare namespace __React { function createClass(spec: ComponentSpec): ClassicComponentClass

; - function createFactory

(type: string): DOMFactory

; - function createFactory

(type: ClassicComponentClass

): ClassicFactory

; - function createFactory

(type: ComponentClass

| StatelessComponent

): Factory

; + function createFactory

( + type: string): DOMFactory; + function createFactory

(type: SFC

): SFCFactory

; + function createFactory

( + type: ClassType, ClassicComponentClass

>): CFactory>; + function createFactory, C extends ComponentClass

>( + type: ClassType): CFactory; + function createFactory

(type: ComponentClass

| SFC

): Factory

; - function createElement

( + function createElement

( type: string, - props?: P, - ...children: ReactNode[]): DOMElement

; + props?: P & ClassAttributes, + ...children: ReactNode[]): DOMElement; function createElement

( - type: ClassicComponentClass

, - props?: P, - ...children: ReactNode[]): ClassicElement

; + type: SFC

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

; function createElement

( - type: ComponentClass

| StatelessComponent

, - props?: P, + type: ClassType, ClassicComponentClass

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

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

( + type: ComponentClass

| SFC

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

; - function cloneElement( - element: ReactHTMLElement, - props?: HTMLProps, - ...children: ReactNode[]): ReactHTMLElement; - function cloneElement( - element: ReactSVGElement, - props?: SVGProps, - ...children: ReactNode[]): ReactSVGElement; + function cloneElement

( + element: DOMElement, + props?: P & ClassAttributes, + ...children: ReactNode[]): DOMElement; function cloneElement

( - element: ClassicElement

, - props?: Q, - ...children: ReactNode[]): ClassicElement

; + 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, + props?: Q, // should be Q & Attributes ...children: ReactNode[]): ReactElement

; - function isValidElement(object: {}): boolean; + function isValidElement

(object: {}): object is ReactElement

; 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 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

= StatelessComponent

; interface StatelessComponent

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

; @@ -159,19 +201,29 @@ declare namespace __React { } interface ComponentClass

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

; contextTypes?: ValidationMap; childContextTypes?: ValidationMap; defaultProps?: P; + displayName?: string; } interface ClassicComponentClass

extends ComponentClass

{ - new(props?: P, context?: any): ClassicComponent; + new(props?: P, context?: any): ClassicComponent; 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, C extends ComponentClass

> = + 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`: + * + * ```ts + * var b: Button; + * var props: ButtonProps & ClassAttributes