Sandeep Gupta
Sandeep Gupta

Reputation: 7250

what is the difference between export and exports in Typescript?

I have read that they do the same thing when on the top level? However, in my case:

This works fine:

export class First{}
export class Second{}

but following gives error:

class First{}
class Second{}
module.exports = exports = {First,Second}

Error: File 'filepath.ts' is not a module.

Upvotes: 1

Views: 5105

Answers (1)

Louis
Louis

Reputation: 151531

Summary

[Pay close attention to the difference between the singular export and the plural exports in what follows. They are not interchangeable.]

Both export ... and export = are treated as export statements by TypeScript. (Yes, even the 2nd one, which looks like a plain assignment, is in fact treated as an export statement.)

module.exports = exports = is a pair of assignments that has no special meaning as far as the TypeScript compiler is concerned. It is a way to export symbols in CommonJS modules.

Both can be used to export symbols (with some workarounds required in the 2nd case to pacify the compiler), but I recommend using the TypeScript export statements over the CommonJS assignments.

Explanation

export ... and export = are treated as export statements by TypeScript. When us use this, the compiler knows you want to export some symbols from your file. If you try to import in another TypeScript module a file using this, everything is fine, because your use of export ... or export = in the first file tells TypeScript "this is a module", and you've clearly indicated to TypeScript what you want to export.

The code module.exports = exports = ... is treated as two assignments, and has no special meaning beyond this. For the TypeScript compiler, it's the same as foo.bar = bar = .... In both cases, TypeScript will perform type checking on the code but it won't treat it as specifically exporting anything. So if you import a file that uses this, you will get the error you saw: Error: File '...' is not a module. Since your file does not contain any import or export statements, TypeScript does not treat the file as a module.

While you can concoct workarounds to use module.exports = exports = ... to export symbols, I don't recommend using module.exports = exports = ... in TypeScript code. This is a CommonJS way of exporting symbols. AMD modules can also in theory support it, but the TypeScript compiler does not make module visible by default when it emits AMD modules. So whatever concoction you'd use to make it work with CommonJS will require more concocting for AMD. And other module formats that exist now or will be developed in the future may not be able to handle it at all. I'd replace it with:

class First{}
class Second{}
export = {First,Second}

When you are using CommonJS, the compiler emits this for the last line:

module.exports = { First: First, Second: Second };

If you set the compiler to emit AMD modules, it will just return { First: First, Second: Second } from the module factory. And will emit something appropriate for other module formats it supports.

In the rare case where I'd need to use a local reference to the object I'm exporting, I'd modify my export to do this:

const ex = { First, Second };
export = ex;

Then ex can be used locally in the module in the same way exports can be used locally in the CommonJS idiom.

Upvotes: 2

Related Questions