Hacker News new | ask | show | jobs
by conaclos 1150 days ago
Something that still stop me from using Deno is the incompatibility between Deno and other tooling regarding the import of TypeScript files. Namely, it is not possible to import a `.ts` file via a `.js` import [0].

[0] https://github.com/denoland/deno/discussions/18293

3 comments

Yeah, this is an annoying problem because it prevents the same code form working in both Deno and everywhere else.

Most frustrating is that (last I checked) there isn’t even an agreed upon plan to resolve the inconsistency, at least for libraries (import maps, though tedious, at least can solve the problem for non-library code).

Which other tooling allows you to import a `.ts` file from a `.js` import? Not knowing much about the issue, this seems like a rather strange decision to me: If I'm importing a `.js` file, and it does not exist, I'd prefer an error message rather than the sort of magic that you're suggesting: "Oh, but I found a `.ts` file with the same name, so let me just go ahead, transpile the file to JavaScript and let you import the result!" That's rather unexpected IMHO.
This is literally how esm support in node works today unless you turn on an experimental feature flag.

https://www.typescriptlang.org/docs/handbook/esm-node.html

Literally most of other tools: TSC, esbuild, bun, swc, babeljs, ... It is even the recommended way in TSC, esbuild and others to import a .ts file in order to emit esm-valid code. I understand the point of Deno. However, it is just too hard to adopt a tool that cannot be used in tandem with others.

I do not know who downvoted my comment: it is not a healthy behavior.

I'm not sure you understand the point of Deno if you say that the Node ecosystem does something strange so Deno should do it, too... Magic file resolution was one of the regrets explicitly mentioned in Ryan's first talk introducing Deno.
I did not say that. I think it is a good thing to do thing properly. File resolution is pretty complex (too complex) in Node/TSC. I would like others tools to support native .ts imports and translate automatically to .js on code emitting. However, it is not going to happen in the short and medium terms.

Using a fallback to .ts files when importing .js files is a minor and straightforward addition to file resolution. And this is a big gain in terms of interoperability with others tools.

I know this doesn't directly address your specific scenario, with the '.js' import. But there is a similar situation that got a lot better with TypeScript 5.

For a long time I was annoyed by the similar problem of Deno's requirement for fully-specified import paths like 'foo/bar.ts' making our Deno code not easily interoperable with our "plain-ass TypeScript" code.

We have an Nx monorepo with a large amount of "library" code, which is really just TypeScript code that uses standard TypeScript path aliases[1]. This code is used by various teams for various things, like Node programs, Svelte/Angular/FrameworkOfTheWeek apps, local utilities and built tooling, etc).

However, until recently, none of these libs worked with Deno, because internally they had to import things like 'foo/bar' and not 'foo/bar.ts'. Changing the imports to 'foo/bar.ts' would make them work in Deno, but break them for everything else.

But TypeScript 5 really changed that with the addition of a new config option (discussed here recently[2]):

    "compilerOptions": {
        "allowImportingTsExtensions": true,

This lets me take a plain-ass TypeScript Nx monorepo library, and add it to my import_map.json, and use it from Deno code as well. (Nx recently released a new plugin to help with this.)

It's still not ideal, because you have to convert all the files to start importing and exporting using the ".ts" extension, and there are probably edge cases where it breaks something. However, I have been using it since the TypeScript 5 betas and I have not hit any problems yet. (Would be very curious to hear any problems other people have had, though.)

[1]: the entries in the "paths" section of tsconfig.json, which let you map your own import names to filesystem locations, so you can

    import { Hoge } from '@acme/hoge';
instead of:

    import { Hoge } from '../../../../libs/util/hoge/src/index.ts';
[2]: Previous discussion: https://news.ycombinator.com/item?id=35185069#35186448