You signed in with another tab or window. Reload to refresh your session.You signed out in another tab or window. Reload to refresh your session.You switched accounts on another tab or window. Reload to refresh your session.Dismiss alert
{{ message }}
Repository navigation
“import b from './b.ts'” is valid JavaScript, but invalid TypeScript #38546
This has been already mentioned several times on different places, that tsc shall accept import b from './b.ts' as valid, despite the .ts exception, but the argument, that the input is valid JavaScript, but invalid TypeScript has never been raised.
I want to use TypeScript to check the types. But to compile the code fast I want to strip the types with @babel/preset-typescript.
When I write in some of my files import x from ./x.ts tsc 3.9.2 says: “An import path cannot end with a .ts extension”, but rollup/@rollup/plugin-babel/@babel-preset-typescript eat the input happy.
When I write instead import x from ./x.js, typescript does eat the input, but rollup/@rollup/plugin-babel/@babel/preset-typescript cannot find the file. Likewise, when I use import x from ./x.
This code, a.js:
importbfrom'./b.ts'console.log(b)
b.ts:
exportdefault'blub'
is valid JavaScript, it just does not work in Node.JS, as the latter refuses to accept .ts file extension.
But when b.ts is delivered with the correct mime type, then this works:
<html><body><scripttype='module' src='./a.js'></script>
Firefox and Epiphany print “blub” on the console.</body></html>
TypeScript is not obligated to issue zero errors on all JavaScript input files, otherwise no one would use it. See other issues on allowing module resolution to find .ts files.
I had to search a lot to find a workaround: import ./b when I mean import ./b.tswith rollup-babel-typescript. But this then compiles in both just typescript or just rollup-babel-transform-typescript. However the output of typescript 3.9 is not executable by NodeJS, when the target is ES2020.
Typescript also reads k.tswhen one writes import ./k.js.
It will be just simpler for everybody, if import in ES6-terms and in TypeScript terms act the same way for local files (except for import type ...). Refusing import b from './b.ts' is not suitable to prevent the user from doing errors, so there is no point to refuse it.
https://www.typescriptlang.org/docs/handbook/module-resolution.html talks in the “Node resolution strategy” about require("./moduleB") that it tries to open ./moduleB.js. But it does not say that import ./moduleB does not work with --target ES2020, while import ./moduleB.js and require("./moduleB") do work:
With a.ts:
importbfrom'./b'console.log(b)
b.ts:
exportdefault'uuuu'
tsc --target es2020 a.ts produces:
a.js:
import b from "./b"
console.log(b)
b.js:
export default "uuu"
When package.json contains “type”:"module", node a.js prints error, that it cannot find module ./b.
So with import b from "./b"tsc --target es2020 emits import b from './b' which is wrong, as NodeJS expects import b from './b.js. So I have to provide as input import b from './b.js' when I mean import from ./b.ts
https://www.typescriptlang.org/docs/handbook/module-resolution.html says nothing about this. And there are more than one typescript language interpreters. In order to make them compatible/interchangable, either import works with relative imports at least in the same way, as ES6 import does, or it needs very clear documentation, that to import b.js, one has to write in ES6 import ./b.js, but in Typescript the user has to write the same, when the target is ES2020, but can also write import ./b for lower targets. In particular in TS for ES2020 one has to write now import ./b.js when in fact ./b.ts is meant, but rollup-babel-transform-typescript are not that smart: they cannot find b.js, because the file is not there.
That link says 'This is the fundamental promise of TypeScript: You can take some JavaScript code, put it in a TypeScript file, and it means the same thing meant before.' which contradicts the subject of this ticket.
TS needs whole program knowledge or file extensions-based conclusions get abandoned. Then the only thing for import to clarify is: is that thing, without rewriting, an existing file, or an existing directory?
All that said, the .ts extension shall disappear, typescript input files get emacs-like headers, and tsc makes sure, that the input and output directories are distinct. Then no filename rewritings happen, the whole output is moved somewhere else.
Or the extension .ts stays, but the javascript engine starts accepting it somehow (as browsers do now based on mime type).
But when the import means a ts file, then having .ts after the import cannot be wrong (as it is now).
Reacted by SancheZz, ryancwalsh, Aleksei Gorb, Eduardo Turiño, Edmund and Alex Bjørlig
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.
Reacted by Dan Mercer, ryancwalsh, Nino Filiu, mildmojo, A. Matías Quezada, Ray Myers, 1步, cole-themeta, dpfg and Christian Oehne
Reacted by ryancwalsh, Vitor L Cavalcanti, libid0nes, Nino Filiu, Manuel Amstutz, mildmojo, A. Matías Quezada, Ray Myers, Jacob Mischka, John Munsch and 9 more
Reacted by David White, libid0nes, Eka, Rob Nice and Alexander Malitsky
Activity
dilyanpalauzov commentedon May 13, 2020
For
@rollup/plugin-babel+@babel/preset-typescriptto work, I just found that I haveimport b from './b'when I mean b.ts, andextensions: ['.ts', '.js']to both@rollup/plugin-node-resolveand@rollup/plugin-babelSince writing
import b from './b'when I meanfrom ./b.tsis not valid ES6-JavaScript logic, it is also not intuitive.For updating the documentation of
@rollup/plugin-babelhow to work with TypeScript imports I filled rollup/plugins#393 .RyanCavanaugh commentedon May 14, 2020
TypeScript is not obligated to issue zero errors on all JavaScript input files, otherwise no one would use it. See other issues on allowing module resolution to find
.tsfiles.dilyanpalauzov commentedon May 14, 2020
I had to search a lot to find a workaround:
import ./bwhen I meanimport ./b.tswith rollup-babel-typescript. But this then compiles in both just typescript or just rollup-babel-transform-typescript. However the output of typescript 3.9 is not executable by NodeJS, when the target is ES2020.Typescript also reads
k.tswhen one writesimport ./k.js.It will be just simpler for everybody, if
importin ES6-terms and in TypeScript terms act the same way for local files (except forimport type ...). Refusingimport b from './b.ts'is not suitable to prevent the user from doing errors, so there is no point to refuse it.https://www.typescriptlang.org/docs/handbook/module-resolution.html talks in the “Node resolution strategy” about
require("./moduleB")that it tries to open./moduleB.js. But it does not say thatimport ./moduleBdoes not work with --target ES2020, whileimport ./moduleB.jsandrequire("./moduleB")do work:With a.ts:
b.ts:
tsc --target es2020 a.tsproduces:When package.json contains “type”:"module",
node a.jsprints error, that it cannot find module ./b.So with
import b from "./b"tsc --target es2020emitsimport b from './b'which is wrong, as NodeJS expectsimport b from './b.js. So I have to provide as inputimport b from './b.js'when I meanimport from ./b.tshttps://www.typescriptlang.org/docs/handbook/module-resolution.html says nothing about this. And there are more than one typescript language interpreters. In order to make them compatible/interchangable, either
importworks with relative imports at least in the same way, as ES6importdoes, or it needs very clear documentation, that to import b.js, one has to write in ES6import ./b.js, but in Typescript the user has to write the same, when the target is ES2020, but can also writeimport ./bfor lower targets. In particular in TS for ES2020 one has to write nowimport ./b.jswhen in fact./b.tsis meant, but rollup-babel-transform-typescript are not that smart: they cannot find b.js, because the file is not there.dilyanpalauzov commentedon May 14, 2020
So TS shall accept
import './b.ts'and emitimport './b.js'.RyanCavanaugh commentedon May 14, 2020
We don't rewrite import paths. See #35589
dilyanpalauzov commentedon May 14, 2020
That link says 'This is the fundamental promise of TypeScript: You can take some JavaScript code, put it in a TypeScript file, and it means the same thing meant before.' which contradicts the subject of this ticket.
TS needs whole program knowledge or file extensions-based conclusions get abandoned. Then the only thing for
importto clarify is: is that thing, without rewriting, an existing file, or an existing directory?All that said, the .ts extension shall disappear, typescript input files get emacs-like headers, and tsc makes sure, that the input and output directories are distinct. Then no filename rewritings happen, the whole output is moved somewhere else.
Or the extension .ts stays, but the javascript engine starts accepting it somehow (as browsers do now based on mime type).
But when the import means a ts file, then having
.tsafter the import cannot be wrong (as it is now).typescript-bot commentedon May 20, 2020
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.
dilyanpalauzov commentedon May 20, 2020
Well, this is not a question.