代码之家  ›  专栏  ›  技术社区  ›  Andy BnOne

我可以为泛型类型的道具设置默认值吗

  •  2
  • Andy BnOne  · 技术社区  · 5 月前

    我对Vue很有经验,但我是打字初学者。 我有一个简单的Checkbox.vue组件和其他道具,我有两个可选的道具checkedValue和uncheckedValue,它们由两个泛型TCheckedValue和TUnchedValue键入。我想为这两个props设置默认值,因为根据定义,泛型可以接受任何类型,所以我应该能够设置checkedValue:true和uncheckedValue:false,但我得到了下一个错误:

    Vue: Type true is not assignable to type
    InferDefault<LooseRequired<{
         label: string;
         checked: boolean;
         indeterminate: boolean;
         checkedValue?: TCheckedValue | undefined;
         uncheckedValue?: TUncheckedValue | undefined;
         error: boolean; 
    }>, TCheckedValue | undefined> | undefined
    
    checkedValue?: InferDefault<LooseRequired<{
         label: string
         checked: boolean
         indeterminate: boolean
         checkedValue?: TCheckedValue
         uncheckedValue?: TUncheckedValue
         error: boolean 
    }>, TCheckedValue | undefined> | undefined
    

    这是我的组件代码:

    <template>
        <div>
            <input
                type="checkbox"
                :id="props.id"
                :class="[
                    'rounded dark:bg-gray-900 border-gray-300 dark:border-gray-700 text-indigo-600 shadow-sm',
                    'focus:ring-indigo-500 dark:focus:ring-indigo-600 dark:focus:ring-offset-gray-800 mr-2'
                ]"
                :value="props.checkedValue"
                :checked="isChecked"
                :indeterminate="props.indeterminate"
                v-bind="$attrs"
                @change="update"
            />
            <InputLabel :inline="true" :for="props.id" :value="props.label" />
        </div>
    </template>
    
    <script setup lang="ts" generic="TCheckedValue, TUncheckedValue">
    import { type InputPropsType } from "@/Composeables/useFormInput";
    import { computed } from "vue";
    import InputLabel from "@/Components/Form/InputLabel.vue";
    
    const props = withDefaults(defineProps<InputPropsType & {
        label: string;
        checked: boolean;
        indeterminate: boolean;
        checkedValue?: TCheckedValue;
        uncheckedValue?: TUncheckedValue;
        error: boolean;
    }>(), {
        checked: false,
        indeterminate: false,
        checkedValue: true,
        uncheckedValue: false,
        error: false,
    });
    
    const emit = defineEmits<{
        (event: 'change', value: TCheckedValue | TUncheckedValue): void
    }>();
    
    const inputValue = defineModel<TCheckedValue | TUncheckedValue>();
    
    const update = (e: Event) => {
        const target = e.target as HTMLInputElement;
        inputValue.value = target.checked ? props.checkedValue : props.uncheckedValue;
        emit('change', inputValue.value);
    };
    
    const isChecked = computed(() =>
        inputValue.value === props.checkedValue || props.checked
    );
    </script>
    

    我花了一个星期的时间与chatGPT和claude AI一起试图解决这个问题,但没有任何乐趣。

    到目前为止我尝试了什么:

    <script setup lang="ts" generic="TCheckedValue extends boolean, TUncheckedValue extends boolean">
    
    <script setup lang="ts" generic="TCheckedValue extends boolean = boolean, TUncheckedValue extends boolean = boolean">
    
    <script setup lang="ts" generic="TCheckedValue = boolean, TUncheckedValue = boolean">
    
    // i've also tried to use unknown and any instead of boolean 
    
    const props = withDefaults(defineProps<InputPropsType & {
        // ...
        checkedValue?: TCheckedValue;
        uncheckedValue?: TUncheckedValue;
    }>(), {
        // ...
        checkedValue: true as unknown as TCheckedValue,
        uncheckedValue: false as unknown as TUncheckedValue,
    });
    
    1 回复  |  直到 5 月前
        1
  •  1
  •   Alexander Nenashev    5 月前

    您可以将默认值的类型添加到道具中:

        checkedValue?: TCheckedValue | true;
        uncheckedValue?: TUncheckedValue | false;
    

    这给了 (property) checkedValue: true | NotUndefined<TCheckedValue> 这似乎是对的。

    你也可以使用破坏道具的新方法:

    const {checkedValue = true, uncheckedValue = false, ...props} = defineProps<{
        label?: string;
        checkedValue?: TCheckedValue;
        uncheckedValue?: TUncheckedValue;
    }>();
    

    这给了 checkedValue: true | TCheckedValue 这似乎也是正确的。