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

Suppressing "The import path cannot end with a '.ts' extension" error? #27481

Closed
mjbvz opened this issue Oct 1, 2018 · 105 comments · Fixed by #51669
Closed

Suppressing "The import path cannot end with a '.ts' extension" error? #27481

mjbvz opened this issue Oct 1, 2018 · 105 comments · Fixed by #51669
Labels
Fix Available A PR has been opened for this issue Question An issue which isn't directly actionable in code VS Code Tracked There is a VS Code equivalent to this issue

Comments

@mjbvz
Copy link
Contributor

mjbvz commented Oct 1, 2018

From @hooper-hc on September 30, 2018 8:45

when i use

import { PI } from './module.1.ts'

import an module .

vscode linter notice me an error

'The import path cannot end with a ".ts" extension. Consider changing to import “./module.1”。'

hao can i hidden the notice ?

Copied from original issue: microsoft/vscode#59690

@mjbvz mjbvz self-assigned this Oct 1, 2018
@mjbvz mjbvz removed the typescript label Oct 1, 2018
@mjbvz mjbvz removed their assignment Oct 1, 2018
@mjbvz mjbvz added the VS Code Tracked There is a VS Code equivalent to this issue label Oct 1, 2018
@ghost
Copy link

ghost commented Oct 1, 2018

Suppose you have two files:
a.ts: import * as b from "./b.ts";
b.ts: export const b: number = 0;

When we compile a.ts, we don't change import specifiers. So the output a.js will contain the same import specifier "./b.ts", although possibly translated to require("./b.ts").
Then when you try to run a.js it will fail, because there will be no b.ts to import from, only b.js. (Or without --outDir where b.js is next to b.ts, it will resolve the import to b.ts, then fail parsing at : number.)

Instead, you should omit the file extension from your imports, or use the .js extension.

@ghost ghost added the Question An issue which isn't directly actionable in code label Oct 1, 2018
@hooper-hc
Copy link

no,I use deno exec the file 。 without compile。

@zhmushan
Copy link

zhmushan commented Dec 24, 2018

@hooper-hc
I think we can set tsconfig as a temporary solution like this:

{
  "compilerOptions": {
    "module": "amd",
    "target": "esnext",
    "baseUrl": ".",
    "paths": {
      "http://*": ["../../../.deno/deps/http/*"],
      "https://*": ["../../../.deno/deps/https/*"],
      "*.ts": ["*"]
    }
  }
}

@reggi
Copy link

reggi commented Dec 30, 2018

I'm using deno as well. I found that commenting // @ts-ignore each line of an import works.

// @ts-ignore
import coerceToArray from './journey.coerce-to-array.ts'
// @ts-ignore
import fnFree from './journey.fn-free.ts'
// @ts-ignore
import fnReduce from './journey.fn-reduce.ts'

Is there anyway to shut this requirement off globally in ts-config?

I also tried @zhmushan's solution and It didn't fix the issue :(

@zhmushan
Copy link

@reggi remove ./
I hope that in the future, we can use a configuration similar to module:deno to simplify the operation.

@luvies
Copy link

luvies commented Feb 17, 2019

Would the TypeScript team be open to adding "module": "deno" to the tsconfig? That way we can support using the .ts extension natively, without needing to resort to something like kitsonk/deno_ls_plugin as a workaround. It could also try and enforce it as well, so if you try and do

import module from 'module';

it would show an error like Cannot have an extensionless import with module:deno (the only imports that are allowed are full URLs, and relative imports starting with ./ or ../). A configuration like that could also support natively searching the $DENO_DIR/deps folder for types, since we currently need to use a path setting to workaround that. On top of this, automatic imports could work properly as well, since they currently always do the extensionless import (meaning you have to manually edit it anyway).

@TomasHubelbauer
Copy link

This seems like a duplicate of #11901 which was unfortunately closed and silenced. This is important for Deno as was said before and I hope TypeScript will make this extension check configurable or even better remove it altogether.

@swansontec
Copy link

In most of the Javascript tooling ecosystem, you can do things like import picture from 'image.png', which obviously isn't Javascript. The assumption is that some tool will know how to transpile the referenced file into Javascript so this works correctly. All types of assets and alternative syntaxes, such as JSX, work this way.

Typescript, on the other hand, expects you to either use a blank extension or the .js extension, which is different from how the rest of the ecosystem works. This causes friction for tools like Deno or rollup.js that expect the original file extension.

If tsc wanted to work more like the rest of the world, it could allow .ts as an extension, and then transform that to .js as part of stripping types at build-time. This is obviously a large change to the way the tsc compiler works. On the other hand, there is a wave of alternative tooling based on Babel and Sucrase beginning to enter the ecosystem, so perhaps there is a long-term benefit in aligning with those tools' way to doing things.

snd added a commit to snd/url-pattern that referenced this issue May 13, 2019
typescript should not enforce this

hopefully microsoft/TypeScript#27481
will get addressed
@athyuttamre
Copy link

Adding my vote here for support for Deno. The current behavior results in TypeScript resolving all types imported in this way to any, which makes developing software for Deno rather difficult.

@jpike88
Copy link

jpike88 commented Jun 27, 2019

Deno's a great idea, but trying to convince the TS team to explicitly allow Deno to resolve modules that way to me is a losing battle. It's much easier for Deno just to handle it because (a) way faster to do so, less effort needed and (b) convincing the TS team to rewire its internals like that is a very uphill battle.

If tsc wanted to work more like the rest of the world

TS is becoming increasingly dominant, it's a good strategy to be as compatible as possible to TS conventions including their tooling. Otherwise projects like Deno will never get traction due to the divergence in something as fundamental as module resolution

@kitsonk
Copy link
Contributor

kitsonk commented Jun 27, 2019

@jpike88 I disagree. I didn't realise this issue existed. There were a couple other issues semi-related which we were tracking. This issue doesn't say anything about the intent of the team. It is still labelled as a question and it could be argued it really is a duplicate of #16577 or #18442.

Ryan's comment though gets to the heart of the problem, that they can possible write out something that satisfies every host, so they restrict it to the most common situation today, which is Node.js's CJS way.

I still think (and I thought I said this in an issue before) is that there might be time for "moduleResolution": "literal" which would do what it says on the tin, and allow TypeScript to assume that whatever runtime host would figure it out/change the module specifiers.

@jpike88
Copy link

jpike88 commented Jun 27, 2019

Ok, but:

#18442
I actually commented in that like two years ago, and it's still after all this time a stage 1 proposal.

#16577
Also over two years old, still in the 'discussion' stage. Also at the rate it's going, not happening any time soon.

I'm just going off the timescale things have been happening for here, and basing their likelihood of ever happening in a medium-term or even long-term timeframe off that.

@typescript-bot
Copy link
Collaborator

This issue has been marked as 'Question' and has seen no recent activity. It has been automatically closed for house-keeping purposes. If you're still waiting on a response, questions are usually better suited to stackoverflow.

@timburgess
Copy link

Similar issue occurs if you want to directly import an .mjs file
e.g. import { forEach } from https://unpkg.com/iterall@1.2.2/index.mjs

wincent added a commit to wincent/wincent that referenced this issue Mar 20, 2020
Sadly, we can't do imports without TS screaming bloody murder in Vim:

    An import path cannot end with a '.d.ts' extension

etc

Related:

    microsoft/TypeScript#27481

We can suppress the error, but either way, the editor can't see the
types, sadly obviating one of the big upsides of using TypeScript.
wincent added a commit to wincent/wincent that referenced this issue Mar 20, 2020
Sadly, we can't do imports without TS screaming bloody murder in Vim:

    An import path cannot end with a '.d.ts' extension

etc

Related:

    microsoft/TypeScript#27481

We can suppress the error, but either way, the editor can't see the
types, sadly obviating one of the big upsides of using TypeScript.
@VitorLuizC
Copy link

This is closed, but it's not fixed.

@ghost
Copy link

ghost commented Apr 12, 2020

If anyone here was just looking for a way to be able to run your TypeScript within both the context of Node.js and Deno, know that Webpack + ts-loader will let you keep ".ts" in your imports.

@Johannes-B-stock
Copy link

I'm having the same issue with moq.ts package. Any solutions?
https://www.npmjs.com/package/moq.ts

@andrewbranch
Copy link
Member

@Johannes-B-stock can you open a new bug for that? I think since it’s recognizable as a package name and not a file, the error is a bug even under the current extension handling logic.

@andrewbranch
Copy link
Member

Actually, I can’t reproduce that—once the package resolves, the error goes away. I.e., you’d see the .ts extension error if you tried to use it without running npm install first, but once it exists in node_modules, the error disappears. You can see this happen on the Playground: https://www.typescriptlang.org/play?#code/JYWwDg9gTgLgBAbzgSQHYCsCmBjGAxAGwEMBzAZzgF84AzKCEOAIhAgEcA6GMpgKCA

@EbenOladutemu

This comment was marked as duplicate.

@EbenOladutemu
Copy link

Removing the .ts when importing solved it for me. i.e import Example from './examplefolder/example'

@Johannes-B-stock
Copy link

Thanks for the hint, I found the issue. I exported this as part of a npm package but moq.ts was not in the dependencies, only in devDependencies. If you then use the package in a project that does not include moq.ts, the issue pops up.

@xgqfrms
Copy link

xgqfrms commented Sep 1, 2022

just needs to remove the .ts extension name

- import * as UIComponents from './index.ts'

+ import * as UIComponents from './index'

@code913
Copy link

code913 commented Sep 1, 2022

just needs to remove the .ts extension name

- import * as UIComponents from './index.ts'

+ import * as UIComponents from './index'

Unfortunately that wouldn't work in Deno.

@maor-benami
Copy link

maor-benami commented Oct 2, 2022

How come this issue is open for 5 years (!!) with no answer or progress whatsoever?

@johnallen-117
Copy link

Using this separate VS Code extension worked for me: https://marketplace.visualstudio.com/items?itemName=ameerthehacker.deno-vscode&ssr=false#overview

I'm using Deno and importing .ts files. Not an ideal solution, but at least there's something.

@basickarl
Copy link

basickarl commented Jan 9, 2023

@andy-ms

Suppose you have two files: a.ts: import * as b from "./b.ts"; b.ts: export const b: number = 0;

When we compile a.ts, we don't change import specifiers. So the output a.js will contain the same import specifier "./b.ts", although possibly translated to require("./b.ts"). Then when you try to run a.js it will fail, because there will be no b.ts to import from, only b.js. (Or without --outDir where b.js is next to b.ts, it will resolve the import to b.ts, then fail parsing at : number.)

Instead, you should omit the file extension from your imports, or use the .js extension.

Late to the party, but why won't TypeScript change import specifiers? It seems rather odd that the file is named a.ts but you are importing a.js.

@jeffmcmahan
Copy link

jeffmcmahan commented Jan 16, 2023

I use custom loaders in Node.js and I cannot stop VSCode from issuing error messages telling me that imports "cannot end" with various file extensions, which is now strictly false no matter what runtime is in use. Why not allow users to set an option to avoid this?

@evanandrewrose
Copy link

As of about a month ago, you can use:

"allowImportingTsExtensions": true

In your tsconfig.json to enable *.ts imports.

@Higgs1
Copy link

Higgs1 commented Feb 3, 2023

As of about a month ago, you can use:

"allowImportingTsExtensions": true

In your tsconfig.json to enable *.ts imports.

When doing do, I get the following error instead.

tsconfig.json:14:35 - error TS5096: Option 'allowImportingTsExtensions' can only be used when either 'noEmit' or 'emitDeclarationOnly' is set.

14     "allowImportingTsExtensions": true,
                                     ~~~~

Found 1 error in tsconfig.json:14

I just want to be able to use TypeScript and ES6 modules together :c

@RyanCavanaugh
Copy link
Member

@Higgs1 what runtime environment is your code executing in?

@Higgs1
Copy link

Higgs1 commented Feb 4, 2023

@Higgs1 what runtime environment is your code executing in?

Currently Deno and modern, standard compliant web browser(s) (Chromiums). Supporting Node too would be nice, but not necessary.

@danb4r
Copy link

danb4r commented Mar 28, 2023

While there is no fix from tsc itself (the #11901 has been closed to collaboration since Jul 2018), I had to write this small script called fix-tsc-es-imports that can be integrated into the building process just after tsc.

It adds a .js extension to all relative imports and exports in the code generated by tsc, solving the issue.

@Higgs1
Copy link

Higgs1 commented Mar 28, 2023

@danb4r Thank you for trying to singlehandedly fix a critical tsc bug. Although using sed is rather hacky, it seems to work very well. It doesn't support dynamic imports (even with a string literal, e.g. const foo = await import('foo')) though, Is that something you plan to add in the future?

@danb4r
Copy link

danb4r commented Mar 28, 2023

Thank you @Higgs1. I will add a dynamic imports fix with string literals on the next forthcoming version. Although, dynamic imports with variables would be out of the scope of the tool. As you mentioned, that is indeed a hack while the tsc team does not fix that in the compiler itself. I'll be glad to deprecate the package as soon as we see tsc doing that job for us.

In the meantime, to deal with dynamic imports with variables I think the best option would be to use tsc as a type checker and type generator, and use Babel's @babel/plugin-syntax-dynamic-import or use Babel ^7.8.

@GervinFung
Copy link

Similar to what @danb4r said and done. This issue is important, which is why ts-add-js-extension was made, the strength of this package is that, it can also find whether you are importing/exporting something.js or something/index.js, and it can find whether you are importing/exporting .js or .mjs, you just have to specify the outDir for this package to work, I try not to bind this tool on tsc or anything related to it (reading outDir in tsconfig.json) and want it to be able to run independently. Try it, it should also solve your problem as it covers a lot of cases

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
Fix Available A PR has been opened for this issue Question An issue which isn't directly actionable in code VS Code Tracked There is a VS Code equivalent to this issue
Projects
None yet
Development

Successfully merging a pull request may close this issue.