--experimental-strip-types should elide imported types
Node Version: v22.9.0
Command: node --experimental-strip-types example.ts
import { Http2SecureServer } from 'http2'; // causes error
//import type { Http2SecureServer } from 'http2'; // no error
console.log('done');
import { Http2SecureServer } from 'http2'; // causes error
^^^^^^^^^^^^^^^^^
SyntaxError: The requested module 'http2' does not provide an export named 'Http2SecureServer'
at ModuleJob._instantiate (node:internal/modules/esm/module_job:171:21)
at async ModuleJob.run (node:internal/modules/esm/module_job:254:5)
at async onImport.tracePromise.__proto__ (node:internal/modules/esm/loader:483:26)
When I import a built in type using import type ... everything seems OK. I wonder if -experimental-strip-types needs to rewrite imports in some cases?
Apologies- this was in part my mistake. Http2SecureServer is not exported by node:http2. The user error was that the IDE and bundler let me get away with the import without using the type keyword.
I think this does bring up an interesting question though: bundlers disregard things exported as a type and only used as a type. It's much harder for --experimental-strip-types to know which imports it can disregard until after it's done a full pass of the source code. And even then, I wonder if it's idempotent to skip any import that was never used as anything except a type.
It's much harder for
--experimental-strip-typesto know which imports it can disregard until after it's done a full pass of the source code. And even then, I wonder if it's idempotent to skip any import that was never used as anything except a type.
According to the spec, importing a specific named imports should not be observable IIUC (i.e. import {whatever} from 'specifier' and import 'specifier' should be equivalent as long as whatever is not used). That being said, it's probably quite tricky to reliably assess whether something is only used as a type, and would come with some speed tradeoff I assume.
The user error was that the IDE and bundler let me get away with the import without using the
typekeyword.
FWIW, there's verbatimModuleSyntax to avoid this trap – as well as a lint rule.
Thank you for the tips!
That being said, it's probably quite tricky to reliably assess whether something is only used as a type, and would come with some speed tradeoff I assume.
It's is impossible to determine that reliably (because the binding could be re-exported). That's why typescript introduced isolatedModules very long ago :)
Note to self: what I'm looking for is called import elision and is documented very nicely with caveats within typescript 5.0+ verbatimModuleSyntax flag.
Discussed here per the earlier link: https://www.typescriptlang.org/tsconfig/#verbatimModuleSyntax
As a result, I'm renaming the issue to --experimental-strip-types should elide imported types