Skip to content

Optional prop with default may incorrectly be undefined in template when exactOptionalPropertyTypes and strictNullChecks are true #5338

Closed
@Dylancyclone

Description

@Dylancyclone

Vue - Official extension or vue-tsc version

2.2.8 and 3.0.0-alpha.4

VSCode version

1.99.3

Vue version

3.5.13

TypeScript version

5.8.3

System Info

System:
    OS: Linux 6.13 Ubuntu 24.04.2 LTS 24.04.2 LTS (Noble Numbat)
    CPU: (8) x64 Intel(R) Core(TM) i7-8665U CPU @ 1.90GHz
    Memory: 2.05 GB / 15.27 GB
    Container: Yes
    Shell: 5.2.21 - /usr/bin/bash
  Binaries:
    Node: 22.14.0 - ~/.nvm/versions/node/v22.14.0/bin/node
    Yarn: 1.22.22 - ~/.nvm/versions/node/v22.14.0/bin/yarn
    npm: 10.9.2 - ~/.nvm/versions/node/v22.14.0/bin/npm

package.json dependencies

{
  "dependencies": {
    "vue": "^3.5.13"
  },
  "devDependencies": {
    "@vitejs/plugin-vue": "^5.2.3",
    "@vue/compiler-sfc": "^3.5.13",
    "typescript": "^5.8.3",
    "vite": "^5.4.18",
    "vue-tsc": "3.0.0-alpha.4" // Error also occurs with 2.2.8
  }
}

Steps to reproduce

  1. In your tsconfig.json, under compilerOptions, enable exactOptionalPropertyTypes and strictNullChecks
    • Note: Setting "strict": true will also enable strictNullChecks and cause the issue
  2. In a component, create an optional prop that has a default value
    Example:
const props = withDefaults(
	defineProps<{
		stringWithDefault?: string
	}>(),
	{
		stringWithDefault: "defaultValue",
	}
)
  1. Pass that variable to another component as a prop that is required (line 17 in the reproduction)
  2. Notice the error:
Type 'string | undefined' is not assignable to type 'string'.
  Type 'undefined' is not assignable to type 'string'.ts(2322)

...even though it is impossible for the variable to ever be undefined.

  1. To confirm, pass the variable as props.stringWithDefault instead of stringWithDefault and notice the error goes away
    • stringWithDefault is (incorrectly) string | undefined while props.stringWithDefault is (correctly) string

What is expected?

When passing the prop in the template, it should never be undefined since there is a default value set. The expected behavior is seen when prepending the variable with props. to use the variable through the props object

What is actually happening?

The variable is possibly undefined even though there is a default value, causing a typescript error when passing it to a prop that is required

Link to minimal reproduction

https://play.vuejs.org/#eNqFU8Fu2zAM/RVOpxZobAzbyXAzbGkP26Er1mC76GLYdOxWljSJblIY/vdRcltnadMiF4nv+eXxiRzEV2uT+x5FJnJfutYSeKTegir05lwK8lIspW47axzBynQWamc6kCJJwy18K4XUUpdGewLrjPVwDtuWmgusi16RP2GYKqxbjdcBzodQkOTJtXrzZ2Z+yWCqBXxcnpyehcMxdsYmWDUcfxcq2Ij0UepTqfN06oa984Wws6og5BtA3nxcDsPjP+3pwTjmKWOR82GxgAuDHrQh2Bp3B4vFhMQMMod/+9ZhdRNVOKgXclKks9S6QaiNUmbLpKjn3xOMSSZHZPN0ryVxxs/E8dftJrn1RvNbcmbA8ZQs3Sp0Py21/DxSZBCRgBXBzY9YI9cjZzfVywbLu1fqt34XalJcO/To7qe8J4wKt0G2FuDLmyvc8fkZ7EzVK2a/Af5Cb1QfPE60b72u2PYeL7r9HqeQ81j7yx2h9k9NPRqNPx4VKXBXlDR1XagwdOjoYf1g8WVfIeGSrnqlVqHzZ0LAx8iSgoc8vNKxKOf2PyWf43dSj/wqTwvyznIdrAbA/7MwL0VYiYPRfm24V02rqrirRqOedpLdDge687zvTZMY/wHSU2oA

Any additional comments?

I originally submitted this issue to vuejs/core , but after further investigation I believe it belongs in this repo. vuejs/core#13236
I don't think this belongs in the core repo because the generated build is completely valid, the error only happens during type checking

The minimum reproduction can demonstrate the issue in the browser, but I was also able to replicate it locally, and can provide a full repository if needed

In the reproduction link, the only changes made to the tsconfig.json file is setting exactOptionalPropertyTypes and strictNullChecks are true. If either are not present, the issue doesn't happen.

I'm not sure if it's relevant, but if you turn the reproduction back to use typescript version 5.6.3 the issue goes away because all the props are of type any. The issue appears in the following 5.7.0-beta version because the type information suddenly appears. I didn't notice anything relevant in a quick skim of the 5.7 release notes.

Related: #3728

Sort of related to vuejs/core#6532 , but different because that issue is about still allowing undefined as a value, where this issue is that undefined is a possible when when it should be impossible

Metadata

Metadata

Assignees

No one assigned

    Labels

    good reproduction ✨This issue provides a good reproduction, we will be able to investigate it first🔨 p3-minor-bug

    Type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions