Description
Suggestion
import require destructuring
✅ 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
When compiling with --module commonjs
, const ... require ...
and import ... from ...
both allow destructuring, but import ... require ...
doesn't. This seems a bit arbitrary, and the errors generated are especially confusing:
// works
import fs = require('fs');
// works
import { readFileSync } from 'fs';
// works
const { readFileSync } = require('fs');
// doesn't work
import { readFileSync } = require('fs');
// ^ String literal expected
// ^~~~~~~~~~~~~~~ 'from' expected
📃 Motivating Example
After reading the 4.5.0-beta announcement, I was surprised to find that using import assignment was not as simple as replacing const
with import
. I was even more surprised to find that this works in both CommonJS and ES6, but not with the syntax mentioned in that announcement.
For a specific example in code, see the code above. Currently, all three syntaxes have potentially undesirable consequences:
- using
import ... from ...
with--esModuleInterop
creates extra code in case the module (in this case,fs
) was compiled the same way. However, this is unnecessary. - using
const ... require ...
produces the code hint'require' call may be converted to an import. ts(80005)
- using
import ... require ...
prevents destructuring.
💻 Use Cases
This isn't a major issue, as I can work around it by manually referring to fs.readFileSync
(as opposed to unqualified readFileSync
), or by destructuring explicitly:
import fs = require('fs');
const { readFileSync } = fs;
However, this creates an equally redundant emit:
const fs = require("fs");
const { readFileSync } = fs;