vue 上的 textarea 不接受 null

textarea on vue not accepting null

我使用: - “vue”:“3.2.26”, - “vee-验证”:“4.5.6”, - “打字稿”:“4.5.4”

在 vue3 上创建 textarea 字段时我 运行 遇到了问题

我有

带有 vee-validate 的示例

import { Field, useForm } from 'vee-validate'

<Field v-slot="{ field, errors }" name="name" type="text">
<VControl icon="feather:edit-2" :has-error="Boolean(formErrors.name)">
<input
    v-bind="field"
    class="input is-primary-focus"
    type="text"
    placeholder="Placeholder"
    autocomplete="name"
    />
<p v-if="errors" class="help is-danger">{{ formErrors.name}}</p>
</VControl>
</Field>

简单的例子

<textarea
    v-model="fieldValues.description"
    class="textarea is-success-focus"
    rows="3"
    placeholder="Description"
></textarea>

型号

export interface iCat {
    id: number
    name: string
    description: string | null
}

但是文本区域return错误

Type 'null' is not assignable to type 'string | number | string[] | undefined'.

用于 vee 验证

const {
    values: fieldValues,
    errors: formErrors,
    handleSubmit,
} = useForm({
    initialValues: {
        id: 0,
        name: '',
        description: ''
    },
    validationSchema: object({
        id: number().required().integer(),
        name: string().required(),
        description: string().notRequired().default(null).nullable()
    }),
})

如果检查@vue/runtime-dom/dist/runtime-dom.d.ts

export interface TextareaHTMLAttributes extends HTMLAttributes {
    ....
    value?: string | string[] | number
    ...
}

如果我查看节点模块,我发现文本区域不接受 null 作为值 - 那么我该如何正确解决这个问题?

不幸的是,您无法将 value 的现有类型更改为 TextareaHTMLAttributes(至少在 TypeScript 4.5.5 中不能)。类型扩充只允许扩展(向类型添加属性,或创建一个新类型来扩展原始 TextareaHTMLAttributes 接口,并为 value 添加新类型)。

解决方法是使用扩展 iCat 的新类型,将其 description 类型更改为 TextareaHTMLAttributesvalue 的预期类型:

  1. 声明一个新类型(名为 "iFieldValues"),使用 Omit to exclude the original description property from iCat, and an intersection 和一个新的 description 属性 类型 [=24] =].

  2. 在从 useForm() 返回的 values 上使用 type assertion (as iFieldValues)。

// MyForm.vue
<script setup lang="ts">
import { toRefs } from 'vue'
import type { TextareaHTMLAttributes } from '@vue/runtime-dom'
import { useForm } from 'vee-validate'
import { object, number, string } from 'yup'

export interface iCat {
    id: number
    name: string
    description: string | null
}
        1️⃣
type iFieldValues = Omit<iCat, 'description'> & {
  description: TextareaHTMLAttributes['value']
}

const {
    values,
    errors: formErrors,
    handleSubmit,
} = useForm({
    initialValues: {
        id: 0,
        name: '',
        description: ''
    },
    validationSchema: object({
      id: number().required().integer(),
      name: string().required(),
      description: string().notRequired().default(null).nullable()
    }),
  })
                                   2️⃣
const fieldValues = values as iFieldValues
</script>