Repository: TypeScript
Issue: Allow destructuring in import assignment
Labels: Suggestion,Awaiting More Feedback

# Suggestion

<!--
  Please fill in each section completely. Thank you!
-->

<!--
  💡 Did you know? TypeScript has over 2,000 open suggestions!
  🔎 Please search thoroughly before logging new feature requests as most common ideas already have a proposal in progress.
  The "Common Feature Requests" section of the FAQ lists many popular requests: https://github.com/Microsoft/TypeScript/wiki/FAQ#common-feature-requests

  Replace the text below:
-->

import require destructuring

## ✅ Viability Checklist

<!--
   Suggestions that don't meet all these criteria are very, very unlikely to be accepted.
   We always recommend reviewing the TypeScript design goals before investing time writing
   a proposal for ideas outside the scope of the project.
-->
My suggestion meets these guidelines:

* [x] This wouldn't be a breaking change in existing TypeScript/JavaScript code
* [x] This wouldn't change the runtime behavior of existing JavaScript code
* [x] This could be implemented without emitting different JS based on the types of the expressions
* [x] This isn't a runtime feature (e.g. library functionality, non-ECMAScript syntax with JavaScript output, new syntax sugar for JS, etc.)
* [x] This feature would agree with the rest of [TypeScript's Design Goals](https://github.com/Microsoft/TypeScript/wiki/TypeScript-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:

```ts
// 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

<!--
  If you were announcing this feature in a blog post, what's a short explanation that shows
  a developer why this feature improves the language?
-->

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

<!--
  What do you want to use this for?
  What shortcomings exist with current approaches?
  What workarounds are you using in the meantime?
-->

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:

```ts
import fs = require('fs');
const { readFileSync } = fs;
```

However, this creates an equally redundant emit:

```js
const fs = require("fs");
const { readFileSync } = fs;
```