Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

React ES6 import issue #5128

Open
dreampulse opened this Issue Jul 29, 2015 · 24 comments

Comments

Projects
None yet
@dreampulse
Copy link
Contributor

dreampulse commented Jul 29, 2015

I try to do this:
import React, {Component} from 'react';

But I don't know how to define the react.d.ts to support this valid ES6 behavior.

The compiler produces this error:
error TS1192: Module '"react"' has no default export.

@basarat

This comment has been minimized.

Copy link
Member

basarat commented Jul 30, 2015

export default react = React; might just work

@jbrantly

This comment has been minimized.

Copy link
Contributor

jbrantly commented Aug 4, 2015

I think what you want is import * as React, {Component} from 'react'; (but I could be wrong, still learning some of this as well 😃)

@jbrantly

This comment has been minimized.

Copy link
Contributor

jbrantly commented Aug 16, 2015

So I've spent quite a bit of time with ES6 recently and I believe that currently import React from 'react'; is technically not valid behavior because React does not use ES6 classes modules and therefore cannot specify a default export.

This syntax does work when using Babel but that's because Babel has basically said that "if using an ES6 import to get a CommonJS module, the default export is the same as modules.export. However, this is entirely a Babel thing and not a spec thing. From the perspective of the spec I would say that import * as React from 'react'; is actually a lot closer in spirit (and it does work with TypeScript out-of-the-box).

@basarat

This comment has been minimized.

Copy link
Member

basarat commented Aug 16, 2015

However, this is entirely a Babel thing and not a spec thing

Agreed. But babel has a lot of traction and people believe that to be the correct way that ES6 modules should behave.

@vvakame has done some work to make the interop with babel type imports smoother : Microsoft/TypeScript#3586

@jbrantly

This comment has been minimized.

Copy link
Contributor

jbrantly commented Aug 17, 2015

Yea, except that PR is mainly about exporting out of TypeScript, whereas this issue is more about importing into TypeScript. In other words, that PR doesn't help with this issue (but it is definitely good for building libraries with TypeScript!).

I suspect this issue will go away soonish as Babel was acqui-hired by Facebook and I wouldn't be surprised at all if React was rewritten as ES6 modules.

Or, if you really want to use that syntax, you can change the declaration file to export default React but you must target ES6 and then use Babel to transpile to CommonJS, otherwise it's not going to work right at runtime (TypeScript will always transpile to moduleName.default when using ES6 imports).

@basarat

This comment has been minimized.

Copy link
Member

basarat commented Aug 17, 2015

Thanks for clarifying. In short we have ts export -> babel import working. Now we need module.exports aliased to default -> ts import working.

@use-strict

This comment has been minimized.

Copy link
Contributor

use-strict commented Sep 23, 2015

I'm a bit late to the party, but from what I know, this is a wontfix from the TypeScript team.

tl;dr: you can't translate an export default into an module.exports =. Use the import ... = require(...) legacy syntax instead :(

Since the ES-6 default export is basically just a regular export with the name 'default' , the equivalent in CJS would be an exports.default =. and the import would look like this in CJS var something = require('something').default. The module.exports = syntax is not sufficient because it makes the module equal the exported symbol itself, making circular dependencies impossible to resolve. This goes against the design of the ES6 modules. IMHO the Babel team went a bit overboard with this :(

@ghost

This comment has been minimized.

Copy link

ghost commented Sep 23, 2015

@dreampulse I'm doing using this syndax:

import {default as React,Component} from 'react';
@webuniverseio

This comment has been minimized.

Copy link
Contributor

webuniverseio commented May 22, 2016

@kataras that doesn't work for me unfortunately:

Error:(2, 9) TS2305: Module '"react"' has no exported member 'default'.

Code

import {default as React, Component, PropTypes} from 'react';

tsconfig.json

{
  "compileOnSave": true,
  "compilerOptions": {
    "target": "es6",
    "sourceMap": true,
    "jsx": "react"
  }
}
@dreampulse

This comment has been minimized.

Copy link
Contributor Author

dreampulse commented May 22, 2016

What is working, is having two imports. Like:

import * as React from "react";
import { Component } from "react";
@ligaz

This comment has been minimized.

Copy link
Contributor

ligaz commented Jan 3, 2017

You can use the allowSyntheticDefaultImports compiler option that will allow this kind of import:

import React, {Component} from 'react';
@bochen2014

This comment has been minimized.

Copy link

bochen2014 commented Jan 20, 2017

thanks @jbrantly. Spot on!!

@tnrich tnrich referenced this issue Apr 13, 2017

Closed

Flow types? #986

@luofish

This comment has been minimized.

Copy link

luofish commented Apr 28, 2017

@ligaz thanks!

@jasperkuperus

This comment has been minimized.

Copy link

jasperkuperus commented May 31, 2017

Just for reference, I had to add "module": "es2015", to the tsconfig.json before the fix mentioned by @ligaz worked for me.

@kkarmalkar

This comment has been minimized.

Copy link

kkarmalkar commented Oct 18, 2017

I am using import React, {Component, PropTypes} from 'react'; and getting error Cannot resolve symbol PropTypes. Any pointer on how to resolve this issue?

@corydeppen

This comment has been minimized.

Copy link
Contributor

corydeppen commented Oct 18, 2017

@kkarmalkar If you're using React >=15.5.0, you'll want to migrate from React.PropTypes to the new prop-types package and definitions.

@kkarmalkar

This comment has been minimized.

Copy link

kkarmalkar commented Oct 19, 2017

Awesome, thank you @corydeppen

@richtera

This comment has been minimized.

Copy link

richtera commented Mar 22, 2018

Even though I have allowSyntheticDefaultImports I can't get

import React, {Component} from 'react';

to work, but using

import React from 'react';
import {Component} from 'react';

works fine. I have my module set to es5. When compiling code for the browser is it suggested to use es6? I added es2015 to my libs property in tsconfig.json.

@SamHH

This comment has been minimized.

Copy link
Contributor

SamHH commented Mar 28, 2018

@richtera Possibly related to?: Microsoft/TypeScript#21621

@richtera

This comment has been minimized.

Copy link

richtera commented Mar 28, 2018

It is related, yes. Curious though that according to this thread it's working for you.

@IAMtheIAM

This comment has been minimized.

Copy link
Contributor

IAMtheIAM commented Nov 13, 2018

Just add a tsconfig option esModuleInterop: true and then you can use default imports i.e. import React from 'react'

If you're using webpack, then you can also ditch babel with this setup.

@richtera

This comment has been minimized.

Copy link

richtera commented Nov 13, 2018

This works now. I think it was related to specific versions of webpack and typescript I had been using at the time. Babel setups are unfortunately still required for non-javascript uses of babel.

@Guck111

This comment has been minimized.

Copy link

Guck111 commented Mar 15, 2019

"allowSyntheticDefaultImports": true

@HuangHongRui

This comment has been minimized.

Copy link

HuangHongRui commented Mar 23, 2019

"module": "es2015
“allowSyntheticDefaultImports”:true

Working ....

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
You can’t perform that action at this time.