Skip to content

TypeScript error (TS2590) when defining a prop as a union type of many (> 315) literal values and a non-primitive type #10514

Open
@cuongvuong-phoenix

Description

@cuongvuong-phoenix

Vue version

3.4.21

Link to minimal reproduction

https://stackblitz.com/edit/vitejs-vite-th8k9t?file=src%2FApp.vue

Steps to reproduce

  1. Define a prop named icon as a union type of at least 315 literal values and a non-primitive type (e.g. object, array, class,...)
  2. Use it via props.icon
  3. TypeScript raises an error with id TS2590: Expression produces a union type that is too complex to represent.
    • vue-tsc --noEmit also raises the same error (can try it in the Stackblitz Terminal)
  4. Just delete 1 literal string from the union type and the error is gone immediately

What is expected?

TypeScript shouldn't raise the error as the number of union literal strings is not that large (only 315). In fact, I'm still able to use the union type in other types seamlessly without any issues.

What is actually happening?

Not sure what is happening but I think the root cause is due to some adjustments on the DefineProps type of @vue/runtime-core starting from version 3.3.9.
I tried the same setup on Vue 3.3.8 and no error was raised.

System Info

System:
    OS: Linux 6.6 EndeavourOS
    CPU: (16) x64 AMD Ryzen 9 6900HS Creator Edition
    Memory: 6.05 GB / 27.10 GB
    Container: Yes
    Shell: 5.9 - /usr/bin/zsh
  Binaries:
    Node: 20.11.1 - ~/.local/share/mise/installs/node/lts/bin/node
    Yarn: 1.22.21 - /usr/bin/yarn
    npm: 10.2.4 - ~/.local/share/mise/installs/node/lts/bin/npm
    pnpm: 7.32.2 - ~/.local/share/pnpm/pnpm
    bun: 1.0.27 - ~/.local/share/mise/installs/bun/latest/bin/bun
    Watchman: 20240211.093623.0 - /usr/bin/watchman
  Browsers:
    Chromium: 122.0.6261.111

Any additional comments?

I think the use-case of defining a prop like this is quite valid because usually, I want the callers to benefit from literal value type checking and auto-completion so they only need to specify a single value whilst giving them the ability to add more relevant properties. It's more "composition over inheritance" I would say.

Metadata

Metadata

Assignees

No one assigned

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions