Repository: prettier/prettier (JavaScript)

Issue:
Non consistent handling of empty directive between Babel and TS
**Prettier 3.5.3**

**Input:**
<!-- prettier-ignore -->
```ts
"foo";
"";
```

**[Babel output](https://prettier.io/playground#N4Igxg9gdgLgprEAuEAdEAzCF0G5VTp4EgA0IEADjAJbQDOyoAhgE6sQDuACmwoymYAbTswCejcgCNWzMAGs4MAMrMAtnAAyNKHGQZh9OOQhSAVnDAwA6rMrIQlVnCOsAbnumyFS5ZTk6AObIMKwArsYgRmo0IeGRcAAelHCsNBqwwgDyKbIwEKzcEPQ0tNAOCAAmZCBJuekIMMIAKqlQbDQu+oaRJVCBQnAAimEQ8N1CRuRm9InKQYMjY3pIBpORAI6j8NwclAIgzPQAtLpwlec1ocw0QkEAwhBqaswOwkI1fQNwAIIwoTQpGEdqltLoJlMQAALGBqITWKGlFz+MBwZT8Uo0NylMQOMD0SQgNwRACSUAusGUYDS1B+5OUMDEgwhkScxTgtmY9hQThcqQ8NR0rhgu2YgReLPI-lYrgcUmYUjgHylaVg1holRgUOQAA4AAzkZxbGjOUXi16rHrkJpSdWa7VIABM5DCRmaCoEa0hcDUisqF0qmmY-TCYrgADECi9-kE3sCICAAL6JoA)**
<!-- prettier-ignore -->
```ts
"foo";
"";
```

**[TS output](https://prettier.io/playground#N4Igxg9gdgLgprEAuEAdEAzCF0G5VTp4EgA0IEADjAJbQDOyoAhgE6sQDuACmwoymYAbTswCejcgCNWzMAGs4MAMrMAtnAAyNKHGQZh9OOQhSAVnDAwA6rMrIQlVnCOsAbnumyFS5ZTk6AObIMKwArsYgRmo0IeGRcAAelHCsNBqwwgDyKbIwEKzcEPQ0tNAOCAAmZCBJuekIMMIAKqlQbDQu+oaRJVCBQnAAimEQ8N1CRuRm9InKQYMjY3pIBpORAI6j8NwclAIgzPQAtLpwlec1ocw0QkEAwhBqaswOwkI1fQNwAIIwoTQpGEdqltLoJlMQAALGBqITWKGlFz+MBwZT8Uo0NylMQOMD0SQgNwRACSUAusGUYDS1B+5OUMDEgwhkScxTgtmY9hQThcqQ8NR0rhgu2YgReLPI-lYrgcjJS9GpNGoNScOhsNEqMChyAAHAAGcjOLY0Zyi8WvVY9chNKTWTXa5AAJnIYSMzWYUgEa0hcDUUnOF0qmmY-TCYrgADECi9-kE3sCICAAL7JoA)**
<!-- prettier-ignore -->
```ts
"foo";
("");
```

**Why?**

Renaming a file from JS to TS should not change its formatting.

**Context**

This seems like a boolean check is done on `ExpressionStatement .directive` instead of a `!= null` check


Discussion:
Would you like to fix it?
PR opened, feel free to update or request changes!



Patch:
diff --git a/src/language-js/needs-parens.js b/src/language-js/needs-parens.js
index ba7307542763..3f89903170d9 100644
--- a/src/language-js/needs-parens.js
+++ b/src/language-js/needs-parens.js
@@ -718,7 +718,7 @@ function needsParens(path, options) {
       if (
         typeof node.value === "string" &&
         parent.type === "ExpressionStatement" &&
-        !parent.directive
+        typeof parent.directive !== "string"
       ) {
         // To avoid becoming a directive
         const grandParent = path.grandparent;
diff --git a/src/language-js/print/literal.js b/src/language-js/print/literal.js
index 0147d7e052c7..25fd9c35b760 100644
--- a/src/language-js/print/literal.js
+++ b/src/language-js/print/literal.js
@@ -55,7 +55,10 @@ function isDirective(path) {
   }
 
   const { parent } = path;
-  return parent.type === "ExpressionStatement" && parent.directive;
+  return (
+    parent.type === "ExpressionStatement" &&
+    typeof parent.directive === "string"
+  );
 }
 
 function printBigInt(raw) {


Test patch:
diff --git a/tests/format/js/directives/format.test.js b/tests/format/js/directives/format.test.js
index 563ea5db17a0..38556bb5381c 100644
--- a/tests/format/js/directives/format.test.js
+++ b/tests/format/js/directives/format.test.js
@@ -42,6 +42,11 @@ runFormatTest(
             // comment
           ` + "\n",
       },
+      {
+        // should be kept as directive for all parsers https://github.com/prettier/prettier/issues/17458
+        code: '"";',
+        output: '"";' + "\n",
+      },
     ],
   },
   ["babel", "flow", "typescript"],