vuejs / core

🖖 Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.
https://vuejs.org/
MIT License
47.37k stars 8.29k forks source link

`null` binding value triggers type error in DOM attributes #8600

Open rchl opened 1 year ago

rchl commented 1 year ago

Vue version

3.3.4

Link to minimal reproduction

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

Steps to reproduce

This issue reproduces with Volar (Vue Language Features) only but since this is about types shipped with Vue, I'm taking a shot at reporting it here.

An element with a native DOM attribute (for example aria attribute but it could be style or many other) whose binding value is set to null results in Volar reporting a type issue.

What is expected?

No type issues - null seems to be supported the same way as undefined at runtime and should result in the attribute being omitted.

What is actually happening?

Volar reports a type issue because null value is not allowed.

Screenshot 2023-06-19 at 00 02 31

System Info

No response

Any additional comments?

No response

rchl commented 4 weeks ago

I'll also paste my recent Vue language features issues since I forgot that I've created this before:

Vue - Official extension or vue-tsc version

2.1.6

VSCode version

1.93.1

Vue version

3.5.8

TypeScript version

5.6.2

System Info

System:
    OS: macOS 14.6.1
    CPU: (10) arm64 Apple M1 Max
    Memory: 6.20 GB / 64.00 GB
    Shell: 5.9 - /bin/zsh
  Binaries:
    Node: 20.16.0 - ~/.nvm/versions/node/v20.16.0/bin/node
    Yarn: 1.22.22 - ~/.yarn/bin/yarn
    npm: 10.8.1 - ~/.nvm/versions/node/v20.16.0/bin/npm
    pnpm: 9.9.0 - ~/.nvm/versions/node/v20.16.0/bin/pnpm
  Browsers:
    Chrome: 129.0.6668.59
    Safari: 18.0
    Safari Technology Preview: 18.0

package.json dependencies

"dependencies": {
    "vue": "^3.5.6"
  },
  "devDependencies": {
    "@vitejs/plugin-vue": "^5.1.3",
    "typescript": "^5.5.3",
    "vite": "^5.4.6",
    "vue-tsc": "^2.1.6"
  }

Steps to reproduce

  1. Create component with optional String props:
  props: {
    msg: {
      type: String,
      default: null,
    },
  },
  1. Pass null to msg prop from the parent component:
<HelloWorld :msg="null" />

What is expected?

No type error

What is actually happening?

src/App.vue:9:16 - error TS2322: Type 'null' is not assignable to type 'string | undefined'.

9   <HelloWorld :msg="null" />

Link to minimal reproduction

https://stackblitz.com/edit/vitejs-vite-3fqeyw?file=tsconfig.json,src%2FApp.vue,src%2Fcomponents%2FHelloWorld.vue,package.json&terminal=dev

Any additional comments?

I'm not sure why is null not allowed. Vue doesn't complain when being passed either undefined or null (see attached reproduction).

Note: regardless whether null or undefined is passed, Vue sets the value to null within the component.

rchl commented 4 weeks ago

Note that those could be treated as two different issues (one for native elements and one for custom components) but it might be good to think about both at the same time.