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

problem with default export #11

Open
Gozala opened this issue Mar 25, 2021 · 0 comments
Open

problem with default export #11

Gozala opened this issue Mar 25, 2021 · 0 comments

Comments

@Gozala
Copy link

Gozala commented Mar 25, 2021

@vmx had reported a problem with default export not passing a type check

multiformats/js-multiformats#66 (comment)

import CID from 'multiformats/cid
import raw from 'multiformats/codecs/raw

In commonjs modules, these kind of imports don't work (same with and without this PR). When I do

const CID = require('multiformats/cid')

I get

error TS2339: Property 'parse' does not exist on type 'typeof import("/some/path/js-multiformats/dist/types/cid")'

I also tried adding

/**
 * @typedef {import('multiformats/cid')} CID
 */

but that didn't help either.

The problem here is that TS expects CID = require('multiformats/cid').default instead. Here is how they put it:

By default (with esModuleInterop false or not set) TypeScript treats CommonJS/AMD/UMD modules similar to ES6 modules. In doing this, there are two parts in particular which turned out to be flawed assumptions:

  • a namespace import like import * as moment from "moment" acts the same as const moment = require("moment")
  • a default import like import moment from "moment" acts the same as const moment = require("moment").default

This mis-match causes these two issues:

  • the ES6 modules spec states that a namespace import (import * as x) can only be an object, by having TypeScript treating it the same as = require("x") then TypeScript allowed for the import to be treated as a function and be callable. This breaks the spec’s recommendations.
  • while accurate to the ES6 modules spec, most libraries with CommonJS/AMD/UMD modules didn’t conform as strictly as TypeScript’s implementation.

In theory esModuleInterop option should fix this, but that does not seem to work in practice.

I think we need to either:

  1. Change how ipjs generates .cjs files, which is either:
  2. Default export goes into exports.default =
  3. Or we do module.exports = thing; thing.default = thing; (I don't like this option)
  4. Just use and support named exports (I'm sure anything else would break some assumption some other tool makes)
  5. Make type generation a job of ipjs instead. And generate two sets of types (this will probably also address Publishing from dist breaks "types" and "typeVersions" fields of package.json #10)
    1. From and for ES modules
    2. From and for cjs modules
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

1 participant