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

[plugin-transform-typescript] Default or named exported interface result in runtime error #7640

Closed
ThaNarie opened this issue Mar 28, 2018 · 13 comments · Fixed by #9944 or #10019
Closed
Assignees
Labels
area: typescript i: bug outdated A closed issue/PR that is archived due to age. Recommended to make a new issue

Comments

@ThaNarie
Copy link

ThaNarie commented Mar 28, 2018

Input Code

interface IEvent {
  type: string;
}

export default IEvent;

Babel/Babylon Configuration (.babelrc, package.json, cli command)

{
  "presets": [
    ["@babel/env", {
      "targets": {
        "browsers": ["last 2 versions"],
        "node": "6"
      },
      "loose": true,
      "useBuiltIns": false
    }],
    "@babel/preset-stage-3",
    "@babel/typescript"
  ],
  "plugins": [
    ["@babel/plugin-transform-runtime", {
      "helpers": true,
      "polyfill": false,
      "regenerator": false,
      "moduleName": "@babel/runtime"
    }]
  ]
}

Expected Behavior

Either:

  • Not referencing (thus exporting) IEvent at all
  • Or, setting IEvent to undefined/null/anything so parsing the file doesn't result in a runtime error

Current Behavior

TS compilation results in:

"use strict";

exports.__esModule = true;
exports.default = void 0;
var _default = IEvent; // <<< IEvent doesn't exist!
exports.default = _default;

Which results in the runtime error:

Uncaught ReferenceError: IEvent is not defined

Possible Solution

When stripping interfaces (or probably any non-value types), either:

  • leave a placeholder value for exports
  • or, detect references in exports and remove those exports

Context

I'm using and re-exporting interfaces in my node modules' 'index.ts' file, so you can use them in other TypeScript projects, e.g.:

// index.ts
import { default as IEvent } from "./lib/IEvent";

// app.ts
import { IEvent } from "seng-event";

When publishing the package, the tsc also runs to generate d.ts files, which makes the code above work in a TS project (babel strips types and generates JS code, tsc generates the definitions).

Workaround
A workaround is to use named exports, since the faulty generated code only happens when using default exports.

export interface IEvent {
  type: string;
}

When using a named export, the export itself will be removed along with the interface, since it's a single statement. The (now empty) file will be imported somewhere, but will just result in an undefined value. This shouldn't matter, since Interfaces themselves are not used at runtime.

Your Environment

software version(s)
Babel 7.0.0-beta.42
node 8.9.1
npm 5.5.1
Operating System macOS 10.13.3

Related

Different but related to #7118 (where that's a syntax/parsing error, while this current issue is a runtime error)


Edit by @nicolo-ribaudo

This also doesn't work with export { interface } (#7641) - repl

@babel-bot
Copy link
Collaborator

Hey @ThaNarie! We really appreciate you taking the time to report an issue. The collaborators
on this project attempt to help as many people as possible, but we're a limited number of volunteers,
so it's possible this won't be addressed swiftly.

If you need any help, or just have general Babel or JavaScript questions, we have a vibrant Slack
community that typically always has someone willing to help. You can sign-up here
for an invite.

@nicolo-ribaudo
Copy link
Member

Related: #7118

@nicolo-ribaudo nicolo-ribaudo changed the title [plugin-transform-typescript] Default exported interface result in runtime error [plugin-transform-typescript] Default or named exported interface result in runtime error Mar 28, 2018
@ThaNarie
Copy link
Author

ThaNarie commented Mar 28, 2018

@nicolo-ribaudo I noticed you changed the topic to include or named, but using named exports does work (and is a current workaround to keep using interfaces, I just rephrased my issue a bit) :)

apepper added a commit to apepper/babel that referenced this issue May 16, 2018
apepper added a commit to apepper/babel that referenced this issue May 16, 2018
@infctr
Copy link

infctr commented Dec 6, 2018

btw this also doesn't work

export { IProps as IComponentProps }

@btmorex
Copy link

btmorex commented Mar 14, 2019

Not sure if what I'm seeing is related or a separate bug, but I experience the same behavior when there is anything else but an exported interface in the file (but I'm not re-exporting imported interfaces). For example:

interface A {}
export default A;

works fine, but:

export const a = () => {};
interface A {}
export default A;

gives me a runtime error.

Note: I haven't tested the above in particular, but my cases are just as trivial.

@leethree
Copy link

leethree commented Apr 8, 2019

I'm getting this as a compile time error: SyntaxError: Export 'xxx' is not defined

@nicolo-ribaudo
Copy link
Member

There is an open PR for that error.

@rifler
Copy link

rifler commented Apr 10, 2019

I've updated

    "@babel/cli": "7.2.3",
    "@babel/core": "7.2.2",
    "@babel/plugin-proposal-class-properties": "7.3.0",
    "@babel/plugin-transform-runtime": "7.2.0",
    "@babel/preset-env": "7.3.1",
    "@babel/preset-react": "7.0.0",
    "@babel/preset-typescript": "7.1.0",

to the latest versions and code below stopped working with SyntaxError: xxx.ts: Export 'MyType' is not defined

type MyType = { field: string };

export { MyType };

There is an open PR for that error.

Where I can see it?

@rifler
Copy link

rifler commented Apr 10, 2019

Oh, it breaks even if I do npm i instead of npm ci. Probably some indirect dependency updates in package-lock.json

@nicolo-ribaudo
Copy link
Member

nicolo-ribaudo commented Apr 10, 2019

Where I can see it?

It's #9766. Sorry if I forgot to link it!

@nicolo-ribaudo
Copy link
Member

cc @airato do you want to take a look at this again?

@airato
Copy link
Contributor

airato commented May 23, 2019

Yes, I'll take a look

@lock lock bot added the outdated A closed issue/PR that is archived due to age. Recommended to make a new issue label Aug 22, 2019
@lock lock bot locked as resolved and limited conversation to collaborators Aug 22, 2019
Sign up for free to subscribe to this conversation on GitHub. Already have an account? Sign in.
Labels
area: typescript i: bug outdated A closed issue/PR that is archived due to age. Recommended to make a new issue
Projects
None yet
8 participants