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

Unable import in TypeScript since v5+ #109

Open
andy1547 opened this issue Mar 22, 2022 · 8 comments · May be fixed by #130
Open

Unable import in TypeScript since v5+ #109

andy1547 opened this issue Mar 22, 2022 · 8 comments · May be fixed by #130

Comments

@andy1547
Copy link

andy1547 commented Mar 22, 2022

Using the latest v5.2.0 package (containing JS and TypeScript index.d.ts), I've tried the following:

Importing with ESM default:

import Long from "long";
import Long from "long/umd";
// these statements give the following error:
TS1259: Module '"node_modules\\long\\index"' can only be default-imported using the 'allowSyntheticDefaultImports' flag

Importing everything with import *, I use this syntax to import CommonJs modules that export a single object (without default) e.g. import * as jquery from 'jquery':

import * as Long from "long";
import * as Long from "long/umd";
TS2497: This module can only be referenced with ECMAScript imports/exports by turning on the 'esModuleInterop' flag and referencing its default export.

When I change my TypeScript module output from ESM to AMD (AMD output permits the require syntax), it will compile:

import Long = require("long");
import Long = require("long/umd");

// unfortunately I'm unable to use this syntax with ESM output, which is a blocker for us: 
TS1202: Import assignment cannot be used when targeting ECMAScript modules. Consider using 'import * as ns from "mod"', 'import {a} from "mod"', 'import d from "mod"', or another module format instead.

It's also possible to get this working with v4.0.0 with @types/long v4.0.1 (separate package before types were bundled in v5+) when using the import * as Long from "long" syntax when module output is ESM.

It seems strange to me that the TypeScript declaration exports with = but the JavaScript exports with an ESM default. I suspect the mix/matching of these styles causes the error. The ESM JS/TS should stick to ESM imports/exports and the UMD JS/TS should stick to UMD exports.

@owstron
Copy link

owstron commented Sep 12, 2022

I was able to import from version 5.0.1 which had export default Long by using import Long from 'long', I could not import it either via import * as Long from 'long', import { Long } from 'long' or import Long from 'long'. With 5.2.0 I had to use import Long = require('long').
Btw, my TsConfig setting is set to { module: 'ESNext' }

smaye81 added a commit to bufbuild/protobuf-es that referenced this issue Nov 11, 2022
This makes the TS compatibility checks a bit more robust by fixing a few
issues in the codebase as well as changing our TypeScript test configs
to include all files rather than just the test files.

Note that the `long` package needed downgraded to `5.0.1` (and pinned to
patches only) because of an issue in that library with 5.2 and above.
See this issue: dcodeIO/long.js#109
@creatorapp
Copy link

Is there any fix coming in for this? Looks like google packages like firebase-admin and firebase-tools depend on this module. With the following tsconfig.json,

  "compilerOptions": {
    "experimentalDecorators": true,
    "esModuleInterop": true,
    "module": "ESNext",
    "target": "esnext",
    "moduleResolution": "nodenext",
    "allowJs": true,
    "strict": false,
    "sourceMap": true,
    "outDir": "dist",
    "rootDir": "./src",
    "emitDecoratorMetadata": true,
    "types": ["reflect-metadata"],
    "lib": ["es6", "dom"]
  },
  "lib": ["es2015"],
  "include": ["src/**/*.ts"]

I continue to get the error:

node_modules/@grpc/proto-loader/build/src/index.d.ts:22:23 - error TS1471: Module 'long' cannot be imported using this construct. The specifier only resolves to an ES module, which cannot be imported with 'require'. Use an ECMAScript import instead.

22 import Long = require('long');

@russellsteadman
Copy link
Contributor

The source of this error is:

export = Long; // compatible with `import Long from "long"`

This is only compatible with synthetic ES modules being exported as CommonJS. For true ES modules this should be:

export default Long;

See the TypeScript documentation which states that separate type definitions can be specified (scroll to the code bubble right after the "The new support works similarly with import conditions." paragraph).

@dcodeIO
Copy link
Owner

dcodeIO commented Apr 15, 2023

Thanks @russellsteadman for the PR! There should be a new release at 0 UTC. Lmk if there are remaining issues with the fix in place.

@magiclen
Copy link

magiclen commented Apr 16, 2023

v5.2.2 shows Module not found: Error: Default condition should be last one when webpack is running. But v5.2.1 does not have this error.

I'm using ESM + Webpack + TS.

@dcodeIO
Copy link
Owner

dcodeIO commented Apr 16, 2023

Reordered in v5.2.3, lmk!

@nhuethmayr
Copy link

Any news on this?

@JustDoItSascha
Copy link

No updates on this for 3 months?

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
8 participants