Skip to content

[vue-component-meta] Non-ASCII prop default values are Unicode-escaped #6010

@ef81sp

Description

@ef81sp

Vue - Official extension or vue-tsc version

vue-component-meta 3.2.6 (also reproduced with 2.2.12 via @storybook/vue3-vite 10.3.4)

VSCode version

N/A (using vue-component-meta via Storybook)

Vue version

3.5.31

TypeScript version

6.0.2

System Info

System:
  OS: macOS 26.4
  CPU: (8) arm64 Apple M1
  Memory: 62.80 MB / 16.00 GB
  Shell: 5.9 - /bin/zsh
Binaries:
  Node: 24.12.0
  pnpm: 10.28.0
Browsers:
  Chrome: 146.0.7680.177

package.json dependencies

{
  "dependencies": {
    "@vitejs/plugin-vue": "^6.0.5",
    "vue": "^3.5.31"
  },
  "devDependencies": {
    "@storybook/addon-docs": "^10.3.4",
    "@storybook/vue3": "^10.3.4",
    "@storybook/vue3-vite": "^10.3.4",
    "storybook": "^10.3.4",
    "typescript": "^6.0.2",
    "vite": "^8.0.3",
    "vue-component-meta": "^3.2.6",
    "vue-tsc": "^3.2.6"
  }
}

Steps to reproduce

When a Vue component has non-ASCII characters (e.g. Japanese) in prop default values, vue-component-meta outputs Unicode escape sequences instead of the original characters.

This affects both destructured defineProps (Vue 3.5+) and withDefaults.

<script setup lang="ts">
const {
  label = 'こんにちは',
  size = '大きい',
} = defineProps<{
  label?: string
  size?: string
}>()
</script>

Minimal (no Storybook):

  1. Clone the reproduction repo
  2. Run pnpm install
  3. Run node --experimental-strip-types repro.ts
  4. Observe the output:
label: default = ""\u3053\u3093\u306B\u3061\u306F""
size: default = ""\u5927\u304D\u3044""

With Storybook:

  1. Clone the reproduction repo and run pnpm install && pnpm storybook
  2. Open the Docs page for the Greeting component
  3. Check the Default column in the props table

What is expected?

Default values should show the original characters:

  • label: こんにちは
  • size: 大きい

What is actually happening?

Default values are Unicode-escaped:

  • label: "\u3053\u3093\u306B\u3061\u306F"
  • size: "\u5927\u304D\u3044"
Image

Link to minimal reproduction

https://github.com/ef81sp/storybook-nihongo

Any additional comments?

The root cause is in vue-component-meta's use of TypeScript's printer.printNode() to serialize default values. The printer is created at checker.ts#L71 via ts.createPrinter(checkerOptions.printer), and the actual printNode calls are at scriptSetup.ts#L43 and #L52.

TypeScript's printer escapes non-ASCII characters by default. Adding neverAsciiEscape: true to the printer options should fix this:

const printer = ts.createPrinter({ ...checkerOptions.printer, neverAsciiEscape: true });

Metadata

Metadata

Assignees

No one assigned

    Type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions