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

import type should not need runtime modules support #44549

Closed
5 tasks done
antoinep92 opened this issue Jun 11, 2021 · 5 comments
Closed
5 tasks done

import type should not need runtime modules support #44549

antoinep92 opened this issue Jun 11, 2021 · 5 comments
Labels
Duplicate An existing issue was already created

Comments

@antoinep92
Copy link

Suggestion

🔍 Search Terms

import type
module
--outFile

✅ Viability Checklist

My suggestion meets these guidelines:

  • This wouldn't be a breaking change in existing TypeScript/JavaScript code
  • This wouldn't change the runtime behavior of existing JavaScript code
  • This could be implemented without emitting different JS based on the types of the expressions
  • This isn't a runtime feature (e.g. library functionality, non-ECMAScript syntax with JavaScript output, new syntax sugar for JS, etc.)
  • This feature would agree with the rest of TypeScript's Design Goals.

⭐ Suggestion

Intuitively I expect import type to be a compile-time only construct. This is currently not really the case, because using import type triggers the compiler into thinking we are using ES modules.

📃 Motivating Example

Consider this test.ts:

import type { mkdir as mkdir_proto } from 'fs';
const { mkdir } = require('fs') as { mkdir: typeof mkdir_proto };

This to compile to a ŧest.js which is more or less:

"use strict";
const { mkdir } = require('fs');

Which does not use ES modules. Nevertheless, the compiler refuses to compile this if modules are disabled, e.g.
tsc test.ts --outFile test.js --target es2020 fails with:

error TS6131: Cannot compile modules using option 'outFile' unless the '--module' flag is 'amd' or 'system'.

1 import type { mkdir as mkdir_proto } from 'fs';

Which makes me think the compilers treats import and import type the same way.

💻 Use Cases

This is clearly not a showstopper, more of an optimization. One use-case is trying to build simple Node.JS scripts, written in typescript as a single file (with the --outFile flag), in order to deploy each script as a single javascript file, that I can run natively on a Node.JS server with no typescript support (no tsc or ts-node installed).
Since the script only has dependency to node's standard library, I was not expecting typescript to refuse to compile as a single file.

We can work arround by defining a tsconfig.json and building in a directory, then extracting the js file generated in that build/ dir. And I realize there are a lot of issues around here about packaging as a single file. But in this case, there is no concatenation required at all. This is just about import type triggering typescript into thinking we are using modules, when we really aren't.

As I said, this is clearly not critical, and I have no idea if this would be easy to implement. So it's really just a suggestion :)

@MartinJohns
Copy link
Contributor

Essentially a duplicate of #41513 and #41562, with a possible solution discussed at #41567.

As soon as you're using the import or export statements you're dealing with modules. This is by design.

@antoinep92
Copy link
Author

I see, thanks, and sorry for the duplicate.
For future reference, this explains the rationale: #35200 (comment)

Although it leaves unanswered the question of how to reference modules, and in particular type modules from script :(

@MartinJohns
Copy link
Contributor

MartinJohns commented Jun 11, 2021

Although it leaves unanswered the question of how to reference modules, and in particular type modules from script :(

That has been answered in the linked issues. In short: You can't. At least currently not.

I stand corrected by @Jamesernator.

@RyanCavanaugh RyanCavanaugh added the Duplicate An existing issue was already created label Jun 11, 2021
@Jamesernator
Copy link

Jamesernator commented Jun 12, 2021

Although it leaves unanswered the question of how to reference modules, and in particular type modules from script :(

That has been answered in the linked issues. In short: You can't. At least currently not.

This isn't entirely true, although it's kinda awkward without proper import. Basically you can use:

type MkdirProto = typeof import("fs")["mkdir"];

This isn't too bad to be honest, although becomes tedious if you want a lot of types as there's no destructuring or such to speak of in the type system. So you'll need a type ImportedType = typeof import("someModule")["ImportedType"] for each and every imported type.

@antoinep92
Copy link
Author

Ah excellent thanks. I saw that from some other comments but wasn't aware this syntax wasn't considered a module import as opposed to import type. Is this documented somewhere ?

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
Duplicate An existing issue was already created
Projects
None yet
Development

No branches or pull requests

4 participants