Repository: prettier/prettier (JavaScript)

Issue:
Vue not formatting TS expression if `script[lang=ts]` is second `<script>`
**Prettier 2.8.6**
[Playground link](https://prettier.io/playground/#N4Igxg9gdgLgprEAuEAeAzmATgSwA4wB8qA9JrgYQDpQbb4wAE6cMArnowDYCGUA5gF4qIGOhHUoXVowAeSZjFwDGAH0ZQ2AWwBGcLI0GMAjDVLkGk1PC15e8SY0bBgjABSynXxj3Tenmrr6AJQAdDAQAGI4snAAJm4ATMGMAL6pZiQ2djwOIAA0IBAEONDoyKA8WFgQAO4AClUI5Sg8XLU8AJ7lhTpYPGAA1qwAyjxacAAyOFBwyABmbSy9-UOjeAMz-MhKbHCFcEFxcfGTfPxsPPxwkRBYWrkwW8ggPGwRBSAAFjBaXADqXxw8HQGzAcBGzWBOAAbsDOi8wOgeiAZiwsDB6v1+A8Fkt9iAAFboWQjLbSACKbAg8DxXGWIA2WHRLxhe0+eGUMH+ODiMC+yAAHAAGQqciAsf79PAvTlwdEwuaFACO1PgWOKLVe6AAtLN4vFPlg4KqcMasVdcUhFvSCSwtDgdlg9oV0OS4ABBGBKHA6d5wer6aazOkMt0CSlqubW-GFGA8HQ8vkCpCJOP9HBcLYAYQgWitIHlAFZPmwWAAVBMtG0MtlwACSUBOsBG9AIHqbIxgnWkobg6SAA)
<!-- prettier-ignore -->
```sh
--parser vue
```

**Input:**
<!-- prettier-ignore -->
```vue
<script></script>
<script setup lang="ts">
let x: string | number = 1
</script>
<template>
  {{ (x      as      number).toFixed(2) }}
</template>
```

**Output:**
<!-- prettier-ignore -->
```vue
<script></script>
<script setup lang="ts">
let x: string | number = 1;
</script>
<template>
  {{ (x      as      number).toFixed(2) }}
</template>

```

**Expected behavior:**

Should parse as TS.  [Vue playground](https://sfc.vuejs.org/#eNp9j81qwzAQhF9l0SmBWKI9mqTQS59CFyfZugrWD7vr1OD63btKTAktVBeNZjUfO7N5LcVeRzSt2fOJQpGXvVuFT6sFjDIWGLrUH7wR9kZnAwpMLbBQSD18QRrjEQkO8KS5B4RgLEMnqBpgnmEzwe10fL/vua2V/BYmPG+et7AsFfETNDsTYskkTeyKvXBOuu1ccX4d6EYt3JzqaZ369uZDpHDrHL+fascL20y9U2VpTBIiWuTYHCl/MpKCvdk9MJyaV6SGMJ2RkP5j/vr6h1uxWmoxyzeu3H5+)


Problem is here

https://github.com/prettier/prettier/blob/c6e026ea28a4832ff51c7485091cf19135451650/src/language-html/print-preprocess.js#L413-L426

Should check any `<script>` instead of only checking the first `<script>`


Hints:

Patch:
diff --git a/src/language-html/print-preprocess.js b/src/language-html/print-preprocess.js
--- a/src/language-html/print-preprocess.js
+++ b/src/language-html/print-preprocess.js
@@ -411,18 +411,13 @@ function addIsSpaceSensitive(ast, options) {
 }
 
 function markTsScript(ast, options) {
-  if (options.parser === "vue") {
-    const vueScriptTag = ast.children.find((child) =>
-      isVueScriptTag(child, options)
+  options.__should_parse_vue_template_with_ts =
+    options.parser === "vue" &&
+    ast.children.some(
+      (child) =>
+        isVueScriptTag(child, options) &&
+        ["ts", "typescript"].includes(child.attrMap.lang)
     );
-    if (!vueScriptTag) {
-      return;
-    }
-    const { lang } = vueScriptTag.attrMap;
-    if (lang === "ts" || lang === "typescript") {
-      options.__should_parse_vue_template_with_ts = true;
-    }
-  }
 }
 
 module.exports = preprocess;


Test patch:
diff --git a/tests/format/vue/multiparser/__snapshots__/jsfmt.spec.js.snap b/tests/format/vue/multiparser/__snapshots__/jsfmt.spec.js.snap
--- a/tests/format/vue/multiparser/__snapshots__/jsfmt.spec.js.snap
+++ b/tests/format/vue/multiparser/__snapshots__/jsfmt.spec.js.snap
@@ -70,6 +70,60 @@ export default {
 ================================================================================
 `;
 
+exports[`lang-ts-multiple-script-tags.vue format 1`] = `
+====================================options=====================================
+parsers: ["vue"]
+printWidth: 80
+                                                                                | printWidth
+=====================================input======================================
+<script></script>
+<script></script>
+<script></script>
+<script></script>
+<script></script>
+<script></script>
+<script setup lang="ts">
+let x:      string |         number = 1
+</script>
+<script></script>
+<script></script>
+<script></script>
+<template>
+  <span
+  v-if=" (x    as string).length  >     0"
+  v-for="a in [1,2,  3,4,5].map(   (x  :    number) => x *   x)"
+  :foo="  (x    as number).toFixed(   2) "
+  >
+  {{ (x      as      number).toFixed(2) }}
+  </span>
+</template>
+
+=====================================output=====================================
+<script></script>
+<script></script>
+<script></script>
+<script></script>
+<script></script>
+<script></script>
+<script setup lang="ts">
+let x: string | number = 1;
+</script>
+<script></script>
+<script></script>
+<script></script>
+<template>
+  <span
+    v-if=" (x    as string).length  >     0"
+    v-for="a in [1,2,  3,4,5].map(   (x  :    number) => x *   x)"
+    :foo="  (x    as number).toFixed(   2) "
+  >
+    {{ (x as number).toFixed(2) }}
+  </span>
+</template>
+
+================================================================================
+`;
+
 exports[`lang-tsx.vue format 1`] = `
 ====================================options=====================================
 parsers: ["vue"]
diff --git a/tests/format/vue/multiparser/lang-ts-multiple-script-tags.vue b/tests/format/vue/multiparser/lang-ts-multiple-script-tags.vue
new file mode 100644
--- /dev/null
+++ b/tests/format/vue/multiparser/lang-ts-multiple-script-tags.vue
@@ -0,0 +1,21 @@
+<script></script>
+<script></script>
+<script></script>
+<script></script>
+<script></script>
+<script></script>
+<script setup lang="ts">
+let x:      string |         number = 1
+</script>
+<script></script>
+<script></script>
+<script></script>
+<template>
+  <span
+  v-if=" (x    as string).length  >     0"
+  v-for="a in [1,2,  3,4,5].map(   (x  :    number) => x *   x)"
+  :foo="  (x    as number).toFixed(   2) "
+  >
+  {{ (x      as      number).toFixed(2) }}
+  </span>
+</template>