Subscribe on changes!

How to use validator in using interface declaration props in Vue3

avatar
Apr 25th 2023

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

avatar
Apr 25th 2023
interface Props {
  propF?: 'success' | 'warning' | 'danger'; 
}
avatar
Apr 25th 2023

defineProps() is actually a Composition API. I don't understand what you mean.

avatar
Apr 25th 2023

defineProps()实际上是一个 Composition API。 我不明白你的意思。

He may want to use the interface to validate props.

avatar
Apr 25th 2023

@Alfred-Skyblue that's impossible. prop's validator is a runtime-only check.

avatar
Apr 25th 2023

deafult values are also runtime only, but it's possible to set them when you're using ts version of defineProps

avatar
Apr 25th 2023

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?

avatar
Apr 25th 2023

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:

  1. Give up the validator and downgrade to what Shyam-Chen mentioned
interface Props {  
  propF?: 'success' | 'warning' | 'danger';   
}
  1. 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);
    },
  },  
});
  1. 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>();
avatar
May 4th 2023
interface Props {
  propF?: 'success' | 'warning' | 'danger'; 
}

verifying simple types is okay, but more complex verifications should not be enough

avatar
Aug 21st 2023

Try to use zod,

@wht300 Not possible with vue's compiler, but possible with https://github.com/so1ve/unplugin-vue-complex-types :D

avatar
Oct 8th 2023

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.