Repository: vercel/nft (javascript)

Issue:
Output from TypeScript 4.4+ no longer traceable
Source code:

```ts
import { join } from 'path'

const file = join(__dirname, 'file.txt')
```

[Output TS 4.3 or older](https://www.typescriptlang.org/play?target=6&module=1&ts=4.3.5#code/JYWwDg9gTgLgBAbzgKwsAdnAvnAZlCEOAcjAEMYALYgKBoGMJ0BneXYAGwFM4BeFNOgAUAfREATYFHRkQXADQl23AHQwAHjGIBKIA):

```js
"use strict";
Object.defineProperty(exports, "__esModule", { value: true });
const path_1 = require("path");
const file = path_1.join(__dirname, 'file.txt');
```

[Output TS 4.4 or newer](https://www.typescriptlang.org/play?target=6&module=1&ts=4.4.4#code/JYWwDg9gTgLgBAbzgKwsAdnAvnAZlCEOAcjAEMYALYgKBoGMJ0BneXYAGwFM4BeFNOgAUAfREATYFHRkQXADQl23AHQwAHjGIBKIA):

```js
"use strict";
Object.defineProperty(exports, "__esModule", { value: true });
const path_1 = require("path");
const file = (0, path_1.join)(__dirname, 'file.txt');
```


Discussion:
@guybedford Thoughts on how to solve this one? It seems like TS is doing this to avoid [this method call](https://2ality.com/2015/12/references.html).
@styfle it should be relatively straightforward to substitute the `(0, path1.join)` as a pattern that is supported by the `path.join` style detection. It could be as simple as adding `(0, path.join)` support to the evaluator in supporting the result of this sequence expression being the result of the right side expression. That would be done by adding `SequenceExpression` here - https://github.com/vercel/nft/blob/main/src/utils/static-eval.ts. There may be other touch points but that's the first approach that comes to mind for a fix.

Patch:
diff --git a/src/utils/static-eval.ts b/src/utils/static-eval.ts
--- a/src/utils/static-eval.ts
+++ b/src/utils/static-eval.ts
@@ -415,6 +415,13 @@ const visitors: Record<string, (this: State, node: Node, walk: Walk) => Promise<
     }
     return { value: obj };
   },
+  'SequenceExpression': async function SequenceExpression(this: State, node: Node, walk: Walk) {
+    if ('expressions' in node && node.expressions.length === 2 && node.expressions[0].type === 'Literal' && node.expressions[0].value === 0 && node.expressions[1].type === 'MemberExpression') {
+      const arg = await walk(node.expressions[1]);
+      return arg;
+    }
+    return undefined;
+  },
   'TemplateLiteral': async function TemplateLiteral(this: State, node: Node, walk: Walk) {
     let val: StaticValue | ConditionalValue = { value: '' };
     for (var i = 0; i < node.expressions.length; i++) {


Test patch:
diff --git a/test/unit/ts-path-join/file.txt b/test/unit/ts-path-join/file.txt
new file mode 100644
--- /dev/null
+++ b/test/unit/ts-path-join/file.txt
@@ -0,0 +1 @@
+file content
\ No newline at end of file
diff --git a/test/unit/ts-path-join/input.js b/test/unit/ts-path-join/input.js
new file mode 100644
--- /dev/null
+++ b/test/unit/ts-path-join/input.js
@@ -0,0 +1,7 @@
+"use strict";
+Object.defineProperty(exports, "__esModule", { value: true });
+const path_1 = require("path");
+// See https://devblogs.microsoft.com/typescript/announcing-typescript-4-4/#more-compliant-indirect-calls-for-imported-functions
+// Also https://2ality.com/2015/12/references.html
+const file = (0, path_1.join)(__dirname, 'file.txt');
+console.log(file);
\ No newline at end of file
diff --git a/test/unit/ts-path-join/output.js b/test/unit/ts-path-join/output.js
new file mode 100644
--- /dev/null
+++ b/test/unit/ts-path-join/output.js
@@ -0,0 +1,5 @@
+[
+  "package.json",
+  "test/unit/ts-path-join/file.txt",
+  "test/unit/ts-path-join/input.js"
+]
\ No newline at end of file