Use ad-hoc code for nested destructuring in require (#40188)

* Use ad-hoc code for nested destructuring in require

Nested destructuring doesn't really map to ES imports:

```js
const { utils: { nub, intercalate } } = require('./monopackage')
```

Previously, isRequireVariableDeclaration walked up binding elements
until it reached a variable declaration. This change instead only walks
up one binding element and stops. Then it's not bound as an alias and
uses the checker-only code to produce types for the nested-imported
identifiers.

Fixes #40143

* revert binder formatting change
This commit is contained in:
Nathan Shively-Sanders 2020-09-10 13:07:58 -07:00 committed by GitHub
parent 45dedd6b87
commit b7c598ea39
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
6 changed files with 138 additions and 1 deletions

View File

@ -1939,7 +1939,9 @@ namespace ts {
export function isRequireVariableDeclaration(node: Node, requireStringLiteralLikeArgument: true): node is RequireVariableDeclaration;
export function isRequireVariableDeclaration(node: Node, requireStringLiteralLikeArgument: boolean): node is VariableDeclaration;
export function isRequireVariableDeclaration(node: Node, requireStringLiteralLikeArgument: boolean): node is VariableDeclaration {
node = getRootDeclaration(node);
if (node.kind === SyntaxKind.BindingElement) {
node = node.parent.parent;
}
return isVariableDeclaration(node) && !!node.initializer && isRequireCall(getLeftmostAccessExpression(node.initializer), requireStringLiteralLikeArgument);
}

View File

@ -0,0 +1,18 @@
tests/cases/conformance/salsa/main.js(5,1): error TS2304: Cannot find name 'chalk'.
==== tests/cases/conformance/salsa/main.js (1 errors) ====
const {
chalk: { grey }
} = require('./mod1');
grey
chalk
~~~~~
!!! error TS2304: Cannot find name 'chalk'.
==== tests/cases/conformance/salsa/mod1.js (0 errors) ====
const chalk = {
grey: {}
};
module.exports.chalk = chalk

View File

@ -0,0 +1,33 @@
//// [tests/cases/conformance/salsa/nestedDestructuringOfRequire.ts] ////
//// [mod1.js]
const chalk = {
grey: {}
};
module.exports.chalk = chalk
//// [main.js]
const {
chalk: { grey }
} = require('./mod1');
grey
chalk
//// [mod1.js]
var chalk = {
grey: {}
};
module.exports.chalk = chalk;
//// [main.js]
var grey = require('./mod1').chalk.grey;
grey;
chalk;
//// [mod1.d.ts]
export namespace chalk {
const grey: {};
}
//// [main.d.ts]
export {};

View File

@ -0,0 +1,31 @@
=== tests/cases/conformance/salsa/main.js ===
const {
chalk: { grey }
>chalk : Symbol(chalk, Decl(mod1.js, 2, 2))
>grey : Symbol(grey, Decl(main.js, 1, 12))
} = require('./mod1');
>require : Symbol(require)
>'./mod1' : Symbol("tests/cases/conformance/salsa/mod1", Decl(mod1.js, 0, 0))
grey
>grey : Symbol(grey, Decl(main.js, 1, 12))
chalk
=== tests/cases/conformance/salsa/mod1.js ===
const chalk = {
>chalk : Symbol(chalk, Decl(mod1.js, 0, 5))
grey: {}
>grey : Symbol(grey, Decl(mod1.js, 0, 15))
};
module.exports.chalk = chalk
>module.exports.chalk : Symbol(chalk, Decl(mod1.js, 2, 2))
>module.exports : Symbol(chalk, Decl(mod1.js, 2, 2))
>module : Symbol(module, Decl(mod1.js, 2, 2))
>exports : Symbol("tests/cases/conformance/salsa/mod1", Decl(mod1.js, 0, 0))
>chalk : Symbol(chalk, Decl(mod1.js, 2, 2))
>chalk : Symbol(chalk, Decl(mod1.js, 0, 5))

View File

@ -0,0 +1,36 @@
=== tests/cases/conformance/salsa/main.js ===
const {
chalk: { grey }
>chalk : any
>grey : {}
} = require('./mod1');
>require('./mod1') : typeof import("tests/cases/conformance/salsa/mod1")
>require : any
>'./mod1' : "./mod1"
grey
>grey : {}
chalk
>chalk : any
=== tests/cases/conformance/salsa/mod1.js ===
const chalk = {
>chalk : { grey: {}; }
>{ grey: {}} : { grey: {}; }
grey: {}
>grey : {}
>{} : {}
};
module.exports.chalk = chalk
>module.exports.chalk = chalk : { grey: {}; }
>module.exports.chalk : { grey: {}; }
>module.exports : typeof import("tests/cases/conformance/salsa/mod1")
>module : { "\"tests/cases/conformance/salsa/mod1\"": typeof import("tests/cases/conformance/salsa/mod1"); }
>exports : typeof import("tests/cases/conformance/salsa/mod1")
>chalk : { grey: {}; }
>chalk : { grey: {}; }

View File

@ -0,0 +1,17 @@
// @allowJs: true
// @checkJs: true
// @outDir: out
// @declaration: true
// @filename: mod1.js
const chalk = {
grey: {}
};
module.exports.chalk = chalk
// @filename: main.js
const {
chalk: { grey }
} = require('./mod1');
grey
chalk