使用 formik 和 yup 对对象数组进行 Formik 验证/错误

Set*_*ske 5 validation typescript reactjs formik

我有一个带有数字网格的表格。比如说,每一行有四个值,并且我们有几行。在我的初始值中,我将它们设置如下:

interface Row {
  value1: number,
  value2: number,
  // ...etc
}

interface InitialValuesInterface {
  grid: Row[];
}

const initialValues: InitialValuesInterface = {
  grid: [...Array(6).keys()].map((row, index) => ({
    value1: 100,
    value2: 200,
    // ... etc
  })),
  ...otherValues
}
Run Code Online (Sandbox Code Playgroud)

所以我们有一个包含 6 个对象的数组,每个对象有 4 个命名值。在我的验证中,我要求您验证表单的这一部分,如下所示:

const validationSchema = Yup.object().shape({
  grid: Yup.array().of(
    Yup.object().shape({
      value1: Yup.min(100, "Must be at least 100").etc(),
      value2: Yup.min(200, "Must be at least 200").etc(),
      // ...etc
    })
  )
})
Run Code Online (Sandbox Code Playgroud)

在我的反应组件中,我记录了每次重新渲染的错误。使用formikProps = useFormikContext(),我可以获得formikProps.errors,并且当我测试这些错误时,我在控制台中看到一个错误对象,它看起来与预期一致:

// console.log(formikProps.errors) after triggering an error in the third row, second cell
{
  grid: Array(3)
    2:
      value2: "Must be at least 200"
}
Run Code Online (Sandbox Code Playgroud)

按预期工作。但是,尝试在我的组件中访问此错误以进行错误处理(我想有条件地为任何给定的错误单元格渲染带有工具提示的错误图标),我遇到了错误。

{formikProps.values.grid.map((row, ind) => (
  <TableCell>
    <input 
      type="number"
      name="[${ind}].value2"
      onChange={formikProps.handleChange}
    />
    {formikProps.errors.grid[ind].value2 && // <-- problem here
      <SomeErrorIconWithMessage />
    }
  </TableCell>
))}
Run Code Online (Sandbox Code Playgroud)

Typescript 根本不喜欢这样。首先它告诉我该对象可能是未定义的。我不能这样做formikProps.errors.grid?[ind].value2,因为当我想要条件检查时(即formikProps.errors?.grid工作正常),打字稿认为我正在启动三元运算符。我也尝试这个(非常难看):

{formikProps.errors.grid &&
 formikProps.errors.grid[ind] &&
 formikProps.errors.grid[ind].value2 &&
   (<SomeErrorIconWithMessage />)
}
Run Code Online (Sandbox Code Playgroud)

但后来我收到一个 ts 错误说

Property 'value2' does not exist on type 'string | FormikErrors<Row>'.
  Property 'value2' does not exist on type 'string'.
Run Code Online (Sandbox Code Playgroud)

问:当我的validationSchema专门将其键入为对象数组时,为什么打字稿假设这可能是一个字符串Row?我可以强制打字稿将其视为Row类型吗?