How to use validator in using interface declaration props in Vue3
What problem does this feature solve?
As is well known, using validator
in Optional APIs, for example:
defineProps({
propF: {
type: String,
validator(value) {
// The value must match one of these strings
return ['success', 'warning', 'danger'].includes(value)
}
}
})
so,how to use validator
in Composition Api
interface Props {
propF: string;
}
...
What does the proposed API look like?
I am not sure if there is a ready-made solution. If so, please @ me. If not, my suggestion is to provide a method similar to withDefault, such as withValidator
deafult values are also runtime only, but it's possible to set them when you're using ts version of defineProps
It seems that this problem can be described as: • Problem premise: The document describes:
defineProps or defineEmits can only use either runtime declaration OR type declaration. Using both at the same time will result in a compile error
• Requirement: The user expects to use defineProps with a type declaration, but in some scenarios, he hopes to use the validator to validate the prop values more flexibly (the scenario I can think of is that the component library is written in TS and published to npm, when the user introduces the component in js, if a value outside the expected range is passed in, it is hoped to print more detailed and friendly error logs to prompt the user). • The user expects: What ways can be used to validate props in detail using the validator API when using defineProps with a type declaration?
I am currently unclear if there is a way to achieve your requirements, but based on my current understanding of Vue's capabilities, I can currently think of the following ways:
- Give up the validator and downgrade to what Shyam-Chen mentioned
interface Props {
propF?: 'success' | 'warning' | 'danger';
}
- Give up describing the complete props through interface and use the following method
const props = defineProps({
typeName: {
type: String as PropType<string>,
validator(value: string) {
return ['success', 'warning', 'danger'].includes(value);
},
},
});
- Try to use zod, warning: I only briefly looked at zod, the following code is untested, I don't know if it's really feasible
import { z } from 'zod';
const PropsSchema = z.object({
propA: z.string().refine((val) => ['success', 'warning', 'danger'].includes(val), {
message: "value need in ['success', 'warning', 'danger']",
}),
});
type Props = z.infer<typeof PropsSchema>;
const props=defineProps<Props>();
interface Props { propF?: 'success' | 'warning' | 'danger'; }
verifying simple types is okay, but more complex verifications should not be enough
Try to use zod,
@wht300 Not possible with vue's compiler, but possible with https://github.com/so1ve/unplugin-vue-complex-types :D
I'm closing this issue because it's more like a question than a feature request. There are very insightful discussions in the previous comments, though. If you have any more specific concerns or ideas, please consider opening an RFC discussion to discuss the specific designs.
For now, I think https://github.com/unplugin/unplugin-vue-complex-types is already a good experimental solution for this issue.