Skip to content

In JS, exporting a global require from TS incorrectly treats it like an export alias #42765

Closed
@sandersn

Description

@sandersn

Found when debugging a different mysterious commonjs bug with @elibarzilay:

  1. Install @types/node for this repro. I couldn't get it to repro on a local module, but I think I'm missing something fairly simple.
// @filename: ns.ts
namespace myAssert {
    export type cool = 'cool'
}
var myAssert = require('assert')

// @filename: test.js
exports.equal = myAssert.equal
exports.equal()

🙁 Actual behavior

  1. exports.equal: (actual: any, expected: any, message: string | Error | undefined): void
  2. Error on exports.equal(): expected 3 arguments.
  3. Also, goto-def on exports.equal goes to the definition of equal in asserts.

🙂 Expected behavior

  1. exports.equal: any
  2. No error on exports.equal()
  3. No goto-def on exports.equal

Discussion

var x = require is not supposed to work in TS. However, resolveEntityName checks whether the wrong node is in a JS file before attempting to resolve require calls:

                if (isInJSFile(name)) {
                    if (namespace.valueDeclaration && ......

name is the name being resolved, but namespace is the one being checked for require. The first line should be if (isInJSFile(namespace.valueDeclaration)). Also the two if should be combined into one.

This is an easy fix -- the hard part is making a standalone test that fails before the fix.

Metadata

Metadata

Assignees

No one assigned

    Labels

    BugA bug in TypeScriptGood First IssueWell scoped, documented and has the green light

    Type

    No type

    Projects

    No projects

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions