Definitelytyped: React 15.0.x support

Created on 20 Apr 2016  路  31Comments  路  Source: DefinitelyTyped/DefinitelyTyped

Hello everyone,

Now only react-0.14.4 is supported which is about a half of year old.
The newest version of React is 15.1.0at the moment.
Is anyone gonna update typings to the latest release of react and react-dom?
I wonder is there any automated tools for this purpose or every single line of d.ts files was written manually?

Thanks for explanations.

Most helpful comment

React 15.3 has added a new type (React.PureComponent), but it (probably) can be defined as just being the same interface as React.Component.

All 31 comments

cc/ @vsiao @RyanCavanaugh

+1

react.d.ts is maintained manually. The typings for 0.14.x should be compatible with v15 as far as I know; the only API changes are removed deprecations. Feel free to file an issue or send a PR if it's broken for you.

React 15.3 has added a new type (React.PureComponent), but it (probably) can be defined as just being the same interface as React.Component.

What about React.StatelessComponent? I also have a ton of issues with @types/react-dom referencing members not exported from React, like ReactElement, CElement, etc. @types/react-router with Requireable and many others.

Maybe I'm missing something else here, but I can't seem to get my project loading and 15.x is a nested dep now with only 0.14 typings available.

So, as it turns out, the issue here was related to the allowJs compilerOptions prop being set to true. Setting this as false fixes the issue. Why this is the case is surely off-topic for this issue, but still puzzles me.

I'm surprised there still are no type definitions for React 15 given that this issue was created more half a year ago. Is there a reason for not upgrading?

Side note: playsInline was added for the video element and is not supported in v14.

@schickling, as mentioned above, React 15 largely exports the same API as 14. So unless if you're using PureComponent, you shouldn't have any trouble using the current typings. And if you do need PureComponent, you're always welcome to send a pull request.

So is the main point that just nobody has done a PR yet updating to React 15?

And as said, the following is breaking our builds:

Side note: playsInline was added for the video element and is not supported in v14.

A major part of React 15 that's also missing is full support for SVG attributes (outlined at the bottom of here). I can open a separate pull request to sync SvgAttributes with that list.

Another large difference between v14 and v15 is that stateless components can return null. I had a quick look but that causes more downstream issues like:

JSX element type 'ReactElement<any> | null' is not a constructor function for JSX elements. Type 'null' is not assignable to type 'ElementClass'.'

Thoughts?

Here is an example of what should be a valid stateless component (in v15):

const Header: React.StatelessComponent<{text: string}> = ({ text }) => {
    if (!text) { return null }

    return <h1 className="some-header">{text}</h1>
}

Actually, above issue is tracked at https://github.com/Microsoft/TypeScript/issues/11566

Yikes, React 15.x is still not supported! Also isn't refs different in React 0.14 and 15 aswell ?

@darkyen: React 15+ is already supported since the core API hasn't changed. There is also an outstanding PR to add missing SVG attributes (https://github.com/DefinitelyTyped/DefinitelyTyped/issues/13101). If there's anything else that you need, please send a PR.

Refs haven't changed, as far as I know.

@vsiao It tells me the refs.foo is a ReactInstance, When it should be a DOMelement in certain cases. https://facebook.github.io/react/docs/refs-and-the-dom.html

https://github.com/DefinitelyTyped/DefinitelyTyped/blob/master/react/index.d.ts#L162

type ReactInstance = Component<any, any> | Element;

You'll have to cast to DOMElement if you want that. I would also advise against using string refs (instead of callback refs) since they can't be strongly typed.

all ES6+ examples use react as import React from 'react' but you can't do that with TS. shouldn't this be fixed?

That's actually a TypeScript problem. Nobody actually implements commonjs mapping to modules correctly yet, with TypeScript being "more wrong" as it guessed commonjs would always map to a namespace import.

If you do import * as React from 'react' in TypeScript/babel/webpack it will work, but that is completely accidental, and will break in the future, so don't do that, unless you have to use TypeScript's modules directly without extra bundling.

I'm having a hard type using SystemJS because of this. for this to work, I need to enable allowSyntheticDefaultImports which is clearly wrong, and breaks other properly typed libraries

@pocesar the synthetic default imports is actually the more future-proof way, though it won't _prevent_ you from incorrectly importing it as a namespace.

The current spec draft (that nobody implements yet) mandates that module.exports be converted into a default export, more or less as if all commonjs modules were wrapped with export default module.exports. babel, webpack and systemjs do provide the default if you do a default import, though, so that part should be future-proof.

got it, the problem is the conflict with libraries that do export the default, and when using "module": "system", hell breaks loose, because SystemJS also tries to synthetically import default

@pocesar can you clarify? In my experience, SystemJS behaves correctly in the presence of true default export.

@aluanhaddad it's a two step procedure, in my case, I use module: 'system' and outFile: 'app.js'. if I use import React from 'react', TS won't be able to compile when not using allowSyntheticDefaultImports, when SystemJS is loading react when using import * as React from 'react', react comes out as { default: { ... } }, and thus doesn't work. the only way it so have allowSyntheticDefaultImports, even though the original typings doesn't say it's export default .... that's why. some other libraries doesn't have a interoperable default export fails when using import * as Something from 'not-interoperable' as well as import Something from 'not-interoperable'

You should always be using and taking advantage of the synthetic default where possible.

Something like this line https://github.com/DefinitelyTyped/DefinitelyTyped/blob/3289762cca59308bf092e4b49ea2242ef27fc23e/types/react/index.d.ts#L66
export = React;

can't be updated to something like https://github.com/Microsoft/TypeScript-Handbook/blob/3eda844624d4bfc0a9506f194a8b9d139dc002b3/pages/Modules.md#jquerydts:
export default React;

?

For some reason allowSyntheticDefaultImports isn't working for me (or at least allowing default imports to work) when using [email protected]...

What version of TypeScript?

[email protected]

I noticed your comment from a while back on a similar issue: https://github.com/Microsoft/TypeScript/issues/7518#issuecomment-295130080

--allowSyntheticDefaultImports doesn't affect emit. If you want it to use it, you need a loader

repo is at https://gitlab.com/jcrben/react-redux-typescript-webpack-starter/commit/1693202553ed04e1fcc50c5b8e30f390b30567a2

I'll probably switch it back to private in a few days but I'll allow for requesting access...

npm run dev runs ts-loader, npm run dev2 runs awesome-typescript-loader

in both cases React isn't being returned

@jcrben you're using an old version of webpack. More importantly, you are targeting CommonJS modules in your tsconfig and that means you need to write

import React = require("react");

Ah, thanks! I think targeting ES modules gave me trouble a while back - bit wary of the bleeding edge - but "module": "ES2015" seems to work. Also went with "target": "ES2015" to stay consistent.

Apologies for derailing the issue a bit.

No problem. --target and --module are independent. If you use --module es2015 or higher, import React as a synthetic default and specify --allowSyntheticDefaultImports. Also, be sure to update to the latest Webpack.

Was this page helpful?
0 / 5 - 0 ratings