Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Typescript adds plain export statement

I am building some typescript/react console app for Node.js.

If there is any import module in the source code it adds the export {}; into the output.

How I can get rid of the stuff please?

I use

  • typescript 4.1.2
  • ts-node
  • tsconfig:
{
    "compilerOptions": {
        "module": "ESNext",
        "jsx": "react",
        "esModuleInterop": true,
        "moduleResolution": "node",
        "skipLibCheck": true,
    },
    "include": [
        "src/**/*"
    ],
    "exclude": [
        "node_modules",
    ]
}

Source code:

import { useState, useEffect } from "react";
console.log("aaa");

Output:

console.log("aaa");
export {}; // <------ the problem

Fun fact: when I remove the import, the export disappear.

like image 631
Tomas Randus Avatar asked Oct 29 '25 14:10

Tomas Randus


2 Answers

With the introduction of modules in ECMAScript 2015, ECMAScript has been split into two slightly incompatible languages: Scripts and Modules. However, there is no way to explicitly mark a resource as either a Script or a Module in-band. The only way to do that is out-of-band, e.g. via HTTP Content-Types or a command line flag that explicitly tells the ECMAScript engine to interpret the file as a Module.

So, in order to make it clear to the ECMAScript execution engine, that this is, in fact, a Module not a Script, the only way is to make sure that the resource can only legally interpreted as a Module and not a Script.

An empty export statement serves that purpose, since it is illegal in Scripts but has no side-effects.

Long story short: you cannot remove the export statement, because that will make the file ambiguous: it is impossible to tell from the source code alone whether the file is a Script or a Module. And for reasons of backwards-compatibility, most ECMAScript engines interpret ambiguous resources as Scripts. (A more strict engine might reject the file altogether, which is also not what you want.)

So, if you remove the export statement, your file will no longer be interpreted as a Module. However, the TypeScript source file is a Module (because it contains an import statement), therefore the compiler must emit the export statement in order to ensure that the compiled file is also a Module.

like image 192
Jörg W Mittag Avatar answered Oct 31 '25 03:10

Jörg W Mittag


From this issue comment, if you are importing it just for typing, use type declaration instead:

type Foo = import("./Foo.js").Foo;

const foo: Foo = {
    fooValue: 0,
};

I found this out while making a Chrome Extension with a Content Script where it cannot be a module but TypeScript keeps adding empty export {} statement to the end of the file.

like image 22
Luke Vo Avatar answered Oct 31 '25 03:10

Luke Vo