Subscribe on changes!

Typescript possible undefined loses type when using withDefaults and setting explicitly to undefined

avatar
Aug 26th 2022

Vue version

^3.2.37

Link to minimal reproduction

https://sfc.vuejs.org/#eNqNUbtuwzAM/BVCix0gsdHVsF0U7dCxH6DFdajEgfWARDcoAv97KSkJ0qXoYpg88u50vIgX56qvBUUj2jD6yREEpMXBPJhDJwUFKXppACbtrCe4eFQrKG81FLxWPECvVrsrUtWxiLxpQBpJozWBYIAOmKEshmIjTVtnSRbgglC7eSBMcm0k6NvEw422vqNiK7LgTg+uOgVr2PslyVwBttxA6sQem4i1FEciF5q6DmqMzk6hsv5Q81/lF0OTxgqD3n16ew7omViKSLFKs7Lk7T3/zmnkhYVw/zusyRB6NYwIH966kF0qa58bCOQnc2C1nFjOy6WpDs4THd9QDctModyjmgwmgjZ9+3KzvVM1sJg8sWcyTvnGFbO/uSrLDXQ90LdDq7JKxbt/3URSe3xKTwR4x3m2cLZ+Zg0+Vp2QxyOtP9U80FM=

Steps to reproduce

View the reproduction link, This does not show the full behavior, it requires a full IDE to view Simply copy and paste the few contents

  1. Create a prop
  2. use withDefaults
  3. set that prop to undefined
  4. That value set to undefined believes that it is not possibly undefined anymore. This works for all other values, except when explicitly stating that a value is undefined.

What is expected?

Values that are set to be undefined, their types will continue to be possibly undefined, whereas others will not.

What is actually happening?

Values set explicitly to undefined will continue to be possibly undefined.

System Info

System:
    OS: Windows 10 10.0.22000
    CPU: (12) x64 AMD Ryzen 5 3600X 6-Core Processor
    Memory: 7.99 GB / 15.93 GB
  Binaries:
    Node: 16.14.2 - C:\Program Files\nodejs\node.EXE
    Yarn: 1.22.15 - C:\Program Files\nodejs\yarn.CMD
    npm: 8.11.0 - C:\Program Files\nodejs\npm.CMD
  Browsers:
    Edge: Spartan (44.22000.120.0), Chromium (104.0.1293.63)
    Internet Explorer: 11.0.22000.120

Any additional comments?

Issue taken from https://github.com/johnsoncodehk/volar/issues/1672 , For some more information view this situation

interface Props { id?: number }

const props = withDefaults(defineProps<Props>(), { id: undefined })

image image

As you can see, withDefaults basically infers that anything set into the withDefaults portion, is never going to be undefined. This works great for most situations, but in this situation, it must remain undefined, and not explicitly setting it to undefined causes Vue to use it in odd ways, (I believe Vue's default behavior will typecast a boolean to false when undefined. Which is why it needs to be explicitly set to undefined)