Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

undefined type in prop could warn #5471

Open
livthomas opened this issue Feb 22, 2022 · 4 comments · May be fixed by #5940
Open

undefined type in prop could warn #5471

livthomas opened this issue Feb 22, 2022 · 4 comments · May be fixed by #5940
Labels
🍰 p2-nice-to-have Priority 2: this is not breaking anything but nice to have it addressed. has PR A pull request has already been submitted to solve the issue scope: script-setup scope: types ✨ feature request New feature or request

Comments

@livthomas
Copy link

Version

3.2.31

Reproduction link

sfc.vuejs.org/

Steps to reproduce

  1. Define a prop with type number | undefined using defineProps function
  2. Try to pass undefined value to this prop
  3. Look at the warning in the dev console

What is expected?

If you define prop type as number | undefined, there should be no warning if you pass undefined value.

What is actually happening?

Vue somehow interprets the type definition as number | null and complains about undefined not matching this type:

[Vue warn]: Invalid prop: type check failed for prop "count". Expected Number | Null, got Undefined

Of course you can use defineProps<{count?: number}>(). But this definition doesn't make the prop required and so an IDE won't warn you if you forget to pass in the value. I want to force all consumers of my component to provide count prop while still being able to pass undefined as a valid value.

@posva
Copy link
Member

posva commented Feb 22, 2022

The type could be number | null but not number | undefined. undefined is meant for non-defined values, so if you want to be able to pass undefined, you must set your prop as optional. To pass a "non-existant" value, pass null instead.

If you still want to have your way of handling undefined, you can pass a custom validator and type: null to accept anything:

defineProps({ count: {
  type: null,
  validator: v => v === undefined || typeof v === 'number',
  required: true,
}});

@posva posva closed this as completed Feb 22, 2022
@livthomas
Copy link
Author

livthomas commented Feb 23, 2022

It could be number | null if I had control over the data that is coming in but I don't. It comes from the API and the field is either present there or not (in which case the value is undefined).

I don't want to put :count="count ?? null" everywhere just because Vue cannot handle undefined. I will rather make the prop optional to get rid of the warning even though the value always needs to be provided.

It would be nice if Vue at least didn't show such misleading warnings.If you cannot make it work as expected, then at least don't change the type from number | undefined to number | null under the hood. It's very confusing. You should rather treat such props as optional if there is no other viable solution.

@loilo
Copy link

loilo commented Feb 27, 2022

To pass a "non-existant" value, pass null instead.

Thank you for the clarification @posva!

It would be nice if Vue at least didn't show such misleading warnings.

I second this. That number | undefined is not possible doesn't really bug me, but the error message mislead me into thinking this was a compiler error on Vue's side instead of a comprehension problem on my side, and it took me quite some time to find this issue.

@posva posva added 🍰 p2-nice-to-have Priority 2: this is not breaking anything but nice to have it addressed. ✨ feature request New feature or request labels Feb 27, 2022
@posva posva changed the title Required undefined prop triggers misleading warning undefined type in prop could warn Feb 27, 2022
@posva posva reopened this Feb 27, 2022
@liulinboyi liulinboyi linked a pull request May 17, 2022 that will close this issue
@akhma-ps
Copy link

Found a workaround. If you want to get rid of the annoying warning, you can specify the type you want, not directly, but through a generic, for example.

type AvoidValidation<T> = T
 
defineProps<{
  modelValue: AvoidValidation<string | undefined>
}>()

This is type-check friendly, you keep the ability to specify the field required. But you sacrifice the default property validation.

@haoqunjiang haoqunjiang added scope: types has PR A pull request has already been submitted to solve the issue scope: script-setup labels Mar 16, 2023
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
🍰 p2-nice-to-have Priority 2: this is not breaking anything but nice to have it addressed. has PR A pull request has already been submitted to solve the issue scope: script-setup scope: types ✨ feature request New feature or request
Projects
None yet
Development

Successfully merging a pull request may close this issue.

5 participants