Nested assignment to a require alias isn't a declaration (#40186)

This is not something we can type correctly, and doesn't work in
Typescript either. Better to ignore it in JS.
This commit is contained in:
Nathan Shively-Sanders 2020-09-01 08:20:56 -07:00 committed by GitHub
parent 5fd5a758a3
commit 378083fcec
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
8 changed files with 92 additions and 5 deletions

View File

@ -2974,6 +2974,10 @@ namespace ts {
if (!isInJSFile(node) && !isFunctionSymbol(parentSymbol)) {
return;
}
const rootExpr = getLeftmostAccessExpression(node.left);
if (isIdentifier(rootExpr) && lookupSymbolForName(container, rootExpr.escapedText)!?.flags & SymbolFlags.Alias) {
return;
}
// Fix up parent pointers since we're going to use these nodes before we bind into them
setParent(node.left, node);
setParent(node.right, node);

View File

@ -2416,7 +2416,7 @@ namespace ts {
function getTargetOfImportEqualsDeclaration(node: ImportEqualsDeclaration | VariableDeclaration, dontResolveAlias: boolean): Symbol | undefined {
if (isVariableDeclaration(node) && node.initializer && isPropertyAccessExpression(node.initializer)) {
const name = (getLeftmostPropertyAccessExpression(node.initializer.expression) as CallExpression).arguments[0] as StringLiteral;
const name = (getLeftmostAccessExpression(node.initializer.expression) as CallExpression).arguments[0] as StringLiteral;
return isIdentifier(node.initializer.name)
? resolveSymbol(getPropertyOfType(resolveExternalModuleTypeByLiteral(name), node.initializer.name.escapedText))
: undefined;

View File

@ -1869,7 +1869,7 @@ namespace ts {
export function getExternalModuleRequireArgument(node: Node) {
return isRequireVariableDeclaration(node, /*requireStringLiteralLikeArgument*/ true)
&& (getLeftmostPropertyAccessExpression(node.initializer) as CallExpression).arguments[0] as StringLiteral;
&& (getLeftmostAccessExpression(node.initializer) as CallExpression).arguments[0] as StringLiteral;
}
export function isInternalModuleImportEqualsDeclaration(node: Node): node is ImportEqualsDeclaration {
@ -1940,7 +1940,7 @@ namespace ts {
export function isRequireVariableDeclaration(node: Node, requireStringLiteralLikeArgument: boolean): node is VariableDeclaration;
export function isRequireVariableDeclaration(node: Node, requireStringLiteralLikeArgument: boolean): node is VariableDeclaration {
node = getRootDeclaration(node);
return isVariableDeclaration(node) && !!node.initializer && isRequireCall(getLeftmostPropertyAccessExpression(node.initializer), requireStringLiteralLikeArgument);
return isVariableDeclaration(node) && !!node.initializer && isRequireCall(getLeftmostAccessExpression(node.initializer), requireStringLiteralLikeArgument);
}
export function isRequireVariableStatement(node: Node, requireStringLiteralLikeArgument = true): node is RequireVariableStatement {
@ -5463,8 +5463,8 @@ namespace ts {
return node.kind === SyntaxKind.NamedImports || node.kind === SyntaxKind.NamedExports;
}
export function getLeftmostPropertyAccessExpression(expr: Expression): Expression {
while (isPropertyAccessExpression(expr)) {
export function getLeftmostAccessExpression(expr: Expression): Expression {
while (isAccessExpression(expr)) {
expr = expr.expression;
}
return expr;

View File

@ -0,0 +1,14 @@
tests/cases/conformance/salsa/bug40140.js(1,19): error TS7016: Could not find a declaration file for module 'untyped'. 'tests/cases/conformance/salsa/node_modules/untyped/index.js' implicitly has an 'any' type.
==== tests/cases/conformance/salsa/bug40140.js (1 errors) ====
const u = require('untyped');
~~~~~~~~~
!!! error TS7016: Could not find a declaration file for module 'untyped'. 'tests/cases/conformance/salsa/node_modules/untyped/index.js' implicitly has an 'any' type.
u.assignment.nested = true
u.noError()
==== tests/cases/conformance/salsa/node_modules/untyped/index.js (0 errors) ====
module.exports = {}

View File

@ -0,0 +1,21 @@
//// [tests/cases/conformance/salsa/namespaceAssignmentToRequireAlias.ts] ////
//// [index.js]
module.exports = {}
//// [bug40140.js]
const u = require('untyped');
u.assignment.nested = true
u.noError()
//// [bug40140.js]
"use strict";
var u = require('untyped');
u.assignment.nested = true;
u.noError();
//// [bug40140.d.ts]
export {};

View File

@ -0,0 +1,12 @@
=== tests/cases/conformance/salsa/bug40140.js ===
const u = require('untyped');
>u : Symbol(u, Decl(bug40140.js, 0, 5))
>require : Symbol(require)
u.assignment.nested = true
>u : Symbol(u, Decl(bug40140.js, 0, 5))
u.noError()
>u : Symbol(u, Decl(bug40140.js, 0, 5))

View File

@ -0,0 +1,23 @@
=== tests/cases/conformance/salsa/bug40140.js ===
const u = require('untyped');
>u : any
>require('untyped') : any
>require : any
>'untyped' : "untyped"
u.assignment.nested = true
>u.assignment.nested = true : true
>u.assignment.nested : any
>u.assignment : any
>u : any
>assignment : any
>nested : any
>true : true
u.noError()
>u.noError() : any
>u.noError : any
>u : any
>noError : any

View File

@ -0,0 +1,13 @@
// @allowJs: true
// @checkJs: true
// @strict: true
// @outDir: out
// @declaration: true
// @filename: node_modules/untyped/index.js
module.exports = {}
// @filename: bug40140.js
const u = require('untyped');
u.assignment.nested = true
u.noError()