Subscribe on changes!

"Missing required prop" warning after mounting component with union as props

avatar
Sep 4th 2023

Vue version

3.3

Link to minimal reproduction

https://play.vuejs.org/#__DEV__eNqFUs1O9DAMfBV/uSxIfFvB3kpZCRAScAAESFxyKa1bAmkSJemyUsi746TaZQ/8nFrP2PHY48BOjZmvRmQlq1xjhfHg0I8GZK36E86842zJlRiMth4CWOwgQmf1ADMqm22pcz2YCedsXqQoPcvZMVdcNVo5D4Pr4SS9sDe7RCk1PGkr23+zfa6qYmpOrSjwOBhZe6QIoHo5XIaQi2OsCooyKpQZPaz+D7pFSUKJz0qJmqRoTWjt2o6zYgcvn2tLxOHRYsKrYtuNHdC4JLUT/fzVaUU7CamQs4YqhUR7a7ygUTgrITOJq2mS9+uMeTviwQZvXrB5+wZ/deuEcXZn0aFd0Y62nK9tj36iLx5ucE3/W5ImHSVl/0Leo9NyTBqntLNRtSR7Jy+rvcqWCdU/uou1R+U2QyWhKTPmfM7IwbS0n0b/kruYL3IdV5G2uHH/j6OarsJYbRzdRYudUHiXoiqQeyU4b0ljhA8IZFoJahye0cbl3j4d1Y8XU7ViRZ+NBgghd4ikrSombtfz+Amh+wLo

Steps to reproduce

Open console; observe warning.

What is expected?

No warning.

alternatively, one of:

  • a proper error which says you can't make the props a union
  • a way to suppress this warning for a specific component (eg an attribute on <script>)

What is actually happening?

image

System Info

System:
    OS: Linux 6.5 Manjaro Linux
    CPU: (12) x64 AMD Ryzen 5 3600 6-Core Processor
    Memory: 19.29 GB / 31.23 GB
    Container: Yes
    Shell: 3.6.1 - /usr/bin/fish
  Binaries:
    Node: 20.5.1 - /usr/bin/node
    Yarn: 1.22.19 - /usr/bin/yarn
    npm: 9.8.1 - /usr/bin/npm
  npmPackages:
    vue: ^3.3.4 => 3.3.4

Any additional comments?

No response

avatar
Sep 4th 2023

Both cross type and union type compiled props are required.

props: {
    foo: { type: String, required: true },
    bar: { type: Number, required: true }
  },

But you can make them optional

<script setup lang="ts">
const props = defineProps<{foo?: string} | {bar?: number}>();
</script>
avatar
Sep 4th 2023

if it's categorically illegal then it should be a proper error which refuses to type-check

avatar
Sep 4th 2023

putting a union in defineProps should, like, be either allowed or not allowed. not this limbo state.

avatar
Sep 4th 2023

cc/ @sxzz

avatar
Sep 4th 2023

similar to https://github.com/vuejs/core/issues/8952 maybe we should generate a runtime validator for prop.

avatar
Sep 5th 2023

Would love it if I could at least suppress the runtime type check warning because other than that it works fine.

avatar
Sep 6th 2023

@edison1105 Should vue core handle this? vue-macros is suitable for this work IMO.

avatar
Sep 6th 2023

This can be listed as an improvement of vue/core at the compiler level

avatar
Sep 12th 2023

Hey, I think this would make the template attributes behave as expected. Can someone confirm this?

File: vuejs/core/packages/runtime-core/src/componentPublicInstance.ts

type UnionOmit<T, K extends keyof any> = T extends T ? Omit<T, K> : never

...
/* line 211 */ ? Partial<Defaults> & UnionOmit<P & PublicProps, keyof Defaults>
...
Screenshot 2023-09-12 at 14 44 55

I took the idea for T extends T from here