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