Skip to content

Vue3 custom element prop type number is string in production builds #13615

Open
vuejs/repl
#354
@david-pw

Description

@david-pw

Vue version

^3.5.16

Link to minimal reproduction

https://play.vuejs.org/#eNqFUk2P0zAQ/SsjX9qK1qEqEaiklaD0AAdYLYhTJJRNJq0Xx45sp60U5b8zdppQrRb2lPi9N28+W/ahrvmpQbZmic2NqB1YdE0NMlOHTcqcTdk2VaKqtXHQQoGlULhrrNPVXmKFykEHpdEVTMhmMkp3uqqvOI/8w2chOtfK9uwOYfOc39STc2jtMSv0+V5rt4Yykxa7GYXfKi3vw6eTHBc5RdnJ/GpN0iTqG6Ly6eGwqmXmkF4AyaCHUmvqMuZxyuAhM/T/mscr6jmJBg1FJNEYzuY0E2qiFAf+aLWiwbXeMmVeLCSab7UT1GTK1hAYz2VS6vOXgDnT4HzA8yPmv5/BH+3FYym7M2jRnDBlI+cyc0DX0/vvX/FC/yNZ6aKRpP4PeY9Wy8bX2Ms+Nqqgsm90odrPYY9CHX7Y/cWhskNTvlCv7II+ZbRXP/N/tf633BV/E+JS1dEUh5t44fK8iVAOTZnlGJZ7ZzQt7uoPfoNrUE31gOb9gNEmn2CU1H/666uDwwbOwh0/YZk10tlpf0rBPBnTbKczusSQYrGc976LZTcj15vzuj2upBCnbdv6suCVD4CuSyIPPj2jXyc0fqg0gBWP+fKtx5z9OaIxf8dXrPsDn602Cw==

Steps to reproduce

When using lang=ts with defineProps<T>() production builds of the component when defined as a custom element defineCustomElement don't coerce string prop attributes to numbers. This works perfectly fine in dev mode.

When referring to the reproduction link, please select the Comp.vue tab, then toggle between DEV and PROD you will see the behavior of the rendered value swapping between 6.03 and 5.50.53. This is stable for some reason when viewing from the App.vue container.

What is expected?

When building vue code for production, defineCustomElement should coerce string props to number props if a valid number string is provided i.e.

<ce-comps project-id="5" />

What is actually happening?

Provided <ce-comps project-id="5" />

const props = defineProps<{projectId: number}>();

props.projectId === 5 // false in production
props.projectId === "5" // true in production

System Info

System:
    OS: Windows 11 10.0.26100
    CPU: (20) x64 13th Gen Intel(R) Core(TM) i7-13700H
    Memory: 31.54 GB / 63.68 GB
  Binaries:
    Node: 22.13.1 - D:\Program Files\nodejs\node.EXE
    Yarn: 4.4.0 - D:\Program Files\nodejs\yarn.CMD
    npm: 10.9.2 - D:\Program Files\nodejs\npm.CMD
    bun: 1.2.9 - ~\.bun\bin\bun.EXE
  Browsers:
    Edge: Chromium (138.0.3351.55)
    Internet Explorer: 11.0.26100.1882
  npmPackages:
    vue: ^3.5.16 => 3.5.16

Any additional comments?

When reverting to this syntax, coercion works as documented here

const props = defineProps({
  projectId: {
    type: Number,
    default: -1,
  },
});

props.projectId === 5 // true in production
props.projectId === "5" // false in production

Related issues: #8987

Metadata

Metadata

Assignees

No one assigned

    Labels

    🔨 p3-minor-bugPriority 3: this fixes a bug, but is an edge case that only affects very specific usage.scope: custom elements

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions