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

TS1471: Module X cannot be imported using this construct.... for type only imports #46213

Closed
simllll opened this issue Oct 4, 2021 · 9 comments
Labels
Working as Intended The behavior described is the intended behavior; this is not a bug

Comments

@simllll
Copy link
Contributor

simllll commented Oct 4, 2021

Bug Report

🔎 Search Terms

ts1471, Module X cannot be imported using this construct. The specifier only resolves to an ES module, which cannot be imported synchronously. Use dynamic import instead.

🕗 Version & Regression Information

with ts 4.5 beta and module set to "node12"

💻 Code

// import only a type from an ES package from a CJS package
import type { AgendaScheduler } from '@hokify/scheduler';

// some other code

🙁 Actual behavior

It's clear to me that we cannot import from an ES package, but is this true also for type only imports? Is it technically really required to load the type definitions (which are only needed for compile time) with a dynamic import? If so, how would that be done?

🙂 Expected behavior

A type only import from an ES package should still work with module node12 mode within a CJS package

@andrewbranch
Copy link
Member

how would that be done?

type AgendaScheduler = import('@hokify/scheduler').AgendaScheduler

should work. The error could be silenced, since it’s really meant to stop you from doing something that’s impossible at runtime, but we need to think about whether it’s more or less confusing for type-only imports to be exempt 😕. @DanielRosenwasser @weswigham thoughts?

@weswigham
Copy link
Member

weswigham commented Oct 5, 2021

Uhhh, I don't think we can/should. The issue being that 'this only resolves to an es module' is a kind of heuristic - technically it didn't resolve at all, we just reran the resolution under esm rules and saw that we got a result there, so report the nicer error. I say that I don't think we can/should, since it'd confuse the issue of cjs vs esm mode resolution (which is already complex) - if a cjs mode resolution is allowed to return an esm mode resolution result but only in type positions and only if there's node cjs mode result, we muddy the waters that much more, and also make adding a cjs resolution at a location where there was previously only an esm resolution into a breaking change, instead of a nonbreaking one.

@weswigham
Copy link
Member

This gets back to what I spoke about at a design meeting awhile back - needing some dedicated type space syntax to configure the resolver in a specific way.

@andrewbranch
Copy link
Member

andrewbranch commented Oct 5, 2021

Oh yeah, this definitely can’t work because it would be indecipherable at a glance what resolution mode a type-only import in a CJS file is using, and that’s very bad. I actually think my suggestion of the type alias wouldn’t work either then, because you’re still going to be locked into ESM resolver mode. Yeah, so this is just the same problem we’ve been discussing, as @weswigham said.

@andrewbranch andrewbranch added the Working as Intended The behavior described is the intended behavior; this is not a bug label Oct 5, 2021
@andrewbranch
Copy link
Member

The error itself is working as intended, with the caveat that we’re still working on the proper way to work around it.

@typescript-bot
Copy link
Collaborator

This issue has been marked 'Working as Intended' and has seen no recent activity. It has been automatically closed for house-keeping purposes.

@Jamesernator
Copy link

Jamesernator commented Oct 9, 2021

Uhhh, I don't think we can/should. The issue being that 'this only resolves to an es module' is a kind of heuristic - technically it didn't resolve at all, we just reran the resolution under esm rules and saw that we got a result there, so report the nicer error. I say that I don't think we can/should, since it'd confuse the issue of cjs vs esm mode resolution (which is already complex) - if a cjs mode resolution is allowed to return an esm mode resolution result but only in type positions and only if there's node cjs mode result, we muddy the waters that much more, and also make adding a cjs resolution at a location where there was previously only an esm resolution into a breaking change, instead of a nonbreaking one.

I think this issue should be reopened as this is not purely an issue with resolution, even when using an umambiguous fully qualified specifier one can still not import types, i.e. both of these report the error in .cts file despite there being no ambiguity:

import type { Foo } from "./foo.mjs";
type Foo = import("./foo.mjs").Foo;

@simllll
Copy link
Contributor Author

simllll commented Nov 19, 2021

how would that be done?

type AgendaScheduler = import('@hokify/scheduler').AgendaScheduler
error TS1471: Module '@hokify/scheduler' cannot be imported using this construct. The specifier only resolves to an ES module, which cannot be imported synchronously. Use dynamic import instead.

4 type AgendaScheduler = import('@hokify/scheduler').AgendaScheduler;
                                ~~~~~~~~~~~~~~~~~~~

.. so I tried it via async await import, but now I'm stuck with #46869

@dj-rabel
Copy link

Not perfect, but at least I found a workaround which does work for compiling as well as code completion in PhpStorm.
Simply put "// @ts-expect-error" above your import line. In my case like this:

// @ts-expect-error
import type { OpenAPI3, PathItemObject } from "openapi-typescript";

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
Working as Intended The behavior described is the intended behavior; this is not a bug
Projects
None yet
Development

No branches or pull requests

6 participants