I have a form which has a grid of numbers. Each row has, say, four values, and we have several rows. In my initialValues, I set them like this:
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
}
So we have an array of 6 objects, each object has 4 named values. In my validation, I'm asking yup to validation this part of the form like so:
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
})
)
})
In my react component, I am logging the errors for every rerender. Using formikProps = useFormikContext(), I can get formikProps.errors, and as I test these errors out, I see an errors object in the console that looks as expected:
// console.log(formikProps.errors) after triggering an error in the third row, second cell
{
grid: Array(3)
2:
value2: "Must be at least 200"
}
Working as expected. However, trying to access this error in my component for error handling (I want to conditionally render an error icon with a tooltip for any given erroring cell), I am running into errors.
{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>
))}
Typescript doesn't like this at all. First it tells me that the object is possibly undefined. I cant do formikProps.errors.grid?[ind].value2 because typescript thinks I'm initiating a ternary operator, when I want the conditional check (i.e. formikProps.errors?.grid - that works fine). I try this as well (very ugly):
{formikProps.errors.grid &&
formikProps.errors.grid[ind] &&
formikProps.errors.grid[ind].value2 &&
(<SomeErrorIconWithMessage />)
}
But then I get a ts error saying
Property 'value2' does not exist on type 'string | FormikErrors<Row>'.
Property 'value2' does not exist on type 'string'.
Q Why is typescript assuming this could be a string, when my validationSchema specifically types it as an array of Row objects? Can I force typescript to treat this as Row type?