You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

Vee-Validate 4结合Yup嵌套对象设置initialValues后类型错误问题

Vee-Validate 4 + TypeScript 嵌套字段类型推断错误解决方法

问题场景

使用组合式API结合Vee-Validate 4定义嵌套表单校验规则时,添加初始值后触发TypeScript类型错误:

Element implicitly has an 'any' type because expression of type "currency.name" can't be used to index
type 'Partial<Record<"currency", string | undefined>>'.
Property 'currency.name' does not exist on type 'Partial<Record<"currency", string | undefined>>'.

核心问题:TypeScript错误推断errors类型为仅包含currency字段的平面结构,而非嵌套结构;同时currency字段被误推断为string类型,而非定义的SelectOption类型。

相关代码:

类型定义

export type SelectOption = {
  name: string
  label?: string
}

表单逻辑(出错版本)

import { useForm, useField } from 'vee-validate'
import { object, string } from 'yup'

const { handleSubmit, errors } = useForm({
  validationSchema: object({
    currency: object().shape({
      name: string().notOneOf(['any'], errorMessages.required),
    }),
  }),
  initialValues: {
    currency: {
      name: 'any',
      label: 'Choose currency',
    },
  }
})
const { value: currency } = useField<SelectOption>('currency')

模板代码

<base-select
  v-model="currency"
  :options="currencies"
  :error="errors['currency.name']"
/>

可行解决方案

方案1:显式声明表单值泛型类型

给useForm传入明确的表单结构泛型,让TypeScript正确推断errors的嵌套类型:

// 先定义完整的表单值类型
type FormValues = {
  currency: SelectOption
}

const { handleSubmit, errors } = useForm<FormValues>({
  validationSchema: object({
    currency: object().shape({
      name: string().notOneOf(['any'], errorMessages.required),
    }),
  }),
  initialValues: {
    currency: {
      name: 'any',
      label: 'Choose currency',
    },
  }
})

此时errors会被正确推断为支持嵌套访问的类型,errors['currency.name']或errors.currency?.name均能通过类型校验。

方案2:直接用路径语法获取嵌套字段错误

通过useField直接指定嵌套字段路径,自动获取该字段的错误信息,无需手动处理errors对象:

// 获取currency.name字段的错误
const { error: currencyNameError } = useField('currency.name')
// 保留currency字段的绑定
const { value: currency } = useField<SelectOption>('currency')

模板中直接使用获取到的错误变量:

<base-select
  v-model="currency"
  :options="currencies"
  :error="currencyNameError"
/>

方案3:优化Yup Schema的类型匹配

确保Yup Schema与TypeScript类型严格对齐,避免推断偏差:

type FormValues = {
  currency: SelectOption
}

// 定义独立的currency Schema并标记为必填
const currencySchema = object({
  name: string().notOneOf(['any'], errorMessages.required),
}).defined() // 强制该对象为必填,避免推断为可选类型

const { handleSubmit, errors } = useForm<FormValues>({
  validationSchema: object({
    currency: currencySchema,
  }),
  initialValues: {
    currency: {
      name: 'any',
      label: 'Choose currency',
    },
  }
})

内容的提问来源于stack exchange,提问作者Ришат Ризванов

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.08.15 10:40:29