From 3d1c6e8f2fdcfc57819f8077d15c5f7094df9cdf Mon Sep 17 00:00:00 2001 From: Zen <843968788@qq.com> Date: Tue, 2 Mar 2021 22:54:31 +0800 Subject: [PATCH] fix(42765): require should not work in ts files (#42792) * add failing test * fix(42765): require should not work in ts files --- src/compiler/checker.ts | 25 +++++------ .../reference/resolveNameWithNamspace.js | 26 +++++++++++ .../reference/resolveNameWithNamspace.symbols | 40 +++++++++++++++++ .../reference/resolveNameWithNamspace.types | 43 +++++++++++++++++++ .../cases/compiler/resolveNameWithNamspace.ts | 21 +++++++++ 5 files changed, 143 insertions(+), 12 deletions(-) create mode 100644 tests/baselines/reference/resolveNameWithNamspace.js create mode 100644 tests/baselines/reference/resolveNameWithNamspace.symbols create mode 100644 tests/baselines/reference/resolveNameWithNamspace.types create mode 100644 tests/cases/compiler/resolveNameWithNamspace.ts diff --git a/src/compiler/checker.ts b/src/compiler/checker.ts index 9d8edbe12a5..592efb9e4f6 100644 --- a/src/compiler/checker.ts +++ b/src/compiler/checker.ts @@ -3144,18 +3144,19 @@ namespace ts { else if (namespace === unknownSymbol) { return namespace; } - if (isInJSFile(name)) { - if (namespace.valueDeclaration && - isVariableDeclaration(namespace.valueDeclaration) && - namespace.valueDeclaration.initializer && - isCommonJsRequire(namespace.valueDeclaration.initializer)) { - const moduleName = (namespace.valueDeclaration.initializer as CallExpression).arguments[0] as StringLiteral; - const moduleSym = resolveExternalModuleName(moduleName, moduleName); - if (moduleSym) { - const resolvedModuleSymbol = resolveExternalModuleSymbol(moduleSym); - if (resolvedModuleSymbol) { - namespace = resolvedModuleSymbol; - } + if ( + namespace.valueDeclaration && + isInJSFile(namespace.valueDeclaration) && + isVariableDeclaration(namespace.valueDeclaration) && + namespace.valueDeclaration.initializer && + isCommonJsRequire(namespace.valueDeclaration.initializer) + ) { + const moduleName = (namespace.valueDeclaration.initializer as CallExpression).arguments[0] as StringLiteral; + const moduleSym = resolveExternalModuleName(moduleName, moduleName); + if (moduleSym) { + const resolvedModuleSymbol = resolveExternalModuleSymbol(moduleSym); + if (resolvedModuleSymbol) { + namespace = resolvedModuleSymbol; } } } diff --git a/tests/baselines/reference/resolveNameWithNamspace.js b/tests/baselines/reference/resolveNameWithNamspace.js new file mode 100644 index 00000000000..2669cbff06c --- /dev/null +++ b/tests/baselines/reference/resolveNameWithNamspace.js @@ -0,0 +1,26 @@ +//// [tests/cases/compiler/resolveNameWithNamspace.ts] //// + +//// [node.d.ts] +declare function require(moduleName: string): any; + +declare module "assert" { + export function equal(actual: any, expected: any, message?: string | Error): void; +} + +//// [ns.ts] +/// +namespace myAssert { + export type cool = 'cool' +} +var myAssert = require('assert') + +//// [app.js] +exports.equal = myAssert.equal +exports.equal() + +//// [ns.js] +/// +var myAssert = require('assert'); +//// [app.js] +exports.equal = myAssert.equal; +exports.equal(); diff --git a/tests/baselines/reference/resolveNameWithNamspace.symbols b/tests/baselines/reference/resolveNameWithNamspace.symbols new file mode 100644 index 00000000000..508839e7fdf --- /dev/null +++ b/tests/baselines/reference/resolveNameWithNamspace.symbols @@ -0,0 +1,40 @@ +=== tests/cases/compiler/node.d.ts === +declare function require(moduleName: string): any; +>require : Symbol(require, Decl(node.d.ts, 0, 0)) +>moduleName : Symbol(moduleName, Decl(node.d.ts, 0, 25)) + +declare module "assert" { +>"assert" : Symbol("assert", Decl(node.d.ts, 0, 50)) + + export function equal(actual: any, expected: any, message?: string | Error): void; +>equal : Symbol(equal, Decl(node.d.ts, 2, 25)) +>actual : Symbol(actual, Decl(node.d.ts, 3, 26)) +>expected : Symbol(expected, Decl(node.d.ts, 3, 38)) +>message : Symbol(message, Decl(node.d.ts, 3, 53)) +>Error : Symbol(Error, Decl(lib.es5.d.ts, --, --), Decl(lib.es5.d.ts, --, --)) +} + +=== tests/cases/compiler/ns.ts === +/// +namespace myAssert { +>myAssert : Symbol(myAssert, Decl(ns.ts, 0, 0), Decl(ns.ts, 4, 3)) + + export type cool = 'cool' +>cool : Symbol(cool, Decl(ns.ts, 1, 20)) +} +var myAssert = require('assert') +>myAssert : Symbol(myAssert, Decl(ns.ts, 0, 0), Decl(ns.ts, 4, 3)) +>require : Symbol(require, Decl(node.d.ts, 0, 0)) + +=== tests/cases/compiler/app.js === +exports.equal = myAssert.equal +>exports.equal : Symbol(equal, Decl(app.js, 0, 0)) +>exports : Symbol(equal, Decl(app.js, 0, 0)) +>equal : Symbol(equal, Decl(app.js, 0, 0)) +>myAssert : Symbol(myAssert, Decl(ns.ts, 0, 0), Decl(ns.ts, 4, 3)) + +exports.equal() +>exports.equal : Symbol(equal, Decl(app.js, 0, 0)) +>exports : Symbol("tests/cases/compiler/app", Decl(app.js, 0, 0)) +>equal : Symbol(equal, Decl(app.js, 0, 0)) + diff --git a/tests/baselines/reference/resolveNameWithNamspace.types b/tests/baselines/reference/resolveNameWithNamspace.types new file mode 100644 index 00000000000..58da5c65f24 --- /dev/null +++ b/tests/baselines/reference/resolveNameWithNamspace.types @@ -0,0 +1,43 @@ +=== tests/cases/compiler/node.d.ts === +declare function require(moduleName: string): any; +>require : (moduleName: string) => any +>moduleName : string + +declare module "assert" { +>"assert" : typeof import("assert") + + export function equal(actual: any, expected: any, message?: string | Error): void; +>equal : (actual: any, expected: any, message?: string | Error) => void +>actual : any +>expected : any +>message : string | Error +} + +=== tests/cases/compiler/ns.ts === +/// +namespace myAssert { + export type cool = 'cool' +>cool : "cool" +} +var myAssert = require('assert') +>myAssert : any +>require('assert') : any +>require : (moduleName: string) => any +>'assert' : "assert" + +=== tests/cases/compiler/app.js === +exports.equal = myAssert.equal +>exports.equal = myAssert.equal : any +>exports.equal : error +>exports : typeof import("tests/cases/compiler/app") +>equal : any +>myAssert.equal : any +>myAssert : any +>equal : any + +exports.equal() +>exports.equal() : error +>exports.equal : error +>exports : typeof import("tests/cases/compiler/app") +>equal : any + diff --git a/tests/cases/compiler/resolveNameWithNamspace.ts b/tests/cases/compiler/resolveNameWithNamspace.ts new file mode 100644 index 00000000000..1eaa8163e5c --- /dev/null +++ b/tests/cases/compiler/resolveNameWithNamspace.ts @@ -0,0 +1,21 @@ +// @module: commonjs +// @allowJs: true +// @outDir: ./out/ + +// @filename: node.d.ts +declare function require(moduleName: string): any; + +declare module "assert" { + export function equal(actual: any, expected: any, message?: string | Error): void; +} + +// @filename: ns.ts +/// +namespace myAssert { + export type cool = 'cool' +} +var myAssert = require('assert') + +// @filename: app.js +exports.equal = myAssert.equal +exports.equal() \ No newline at end of file