# React v0.14.4 Type Definitions

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`

## 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> = ...
    ```
