Основная проблема, с которой вы столкнулись в настоящее время, состоит в том, что тип FormErrors
говорит, что он имеет ключ, соответствующий каждому ключу V, и до тех пор, пока не завершится редукция, это не так.
У вас есть пара параметры:
Передайте обобщенные значения, чтобы уменьшить, чтобы сделать тип возвращаемого значения Partial<FormErrors<V>>
, и приведите к FormErrors в конце:
export function getInitialErrors<V extends KeyValue> (data: V): FormErrors<V> {
return Object.keys(data).reduce<Partial<FormErrors<V>>>((acc, key) => (
{ ...acc, [key]: [] }
), {}) as FormErrors<V>
}
Вы можете просто немного теперь отбрасываем возвращаемый тип функции, так как он все равно четко определен приведением. Это, пожалуй, самый правильный вариант (он действительно является частичным во время сокращения, и тогда вы четко заявляете, что думаете, что теперь он завершен только в конце), но он немного грязный.
Установите тип acc
на Partial<FormErrors<V>>
(т. Е. Укажите реальный тип acc
). Это немного удивляет меня, но это, кажется, работает:
export function getInitialErrors<V extends KeyValue> (data: V): FormErrors<V> {
return Object.keys(data).reduce((acc: Partial<FormErrors<V>>, key) => (
{ ...acc, [key]: [] }
), {})
}
Это довольно хороший баланс между корректностью и читабельностью imo.
Сделайте ключи в FormErrors
необязательно (т.е. сделать это [K in keyof V]?: string[]
). Это работает и делает ваш код полностью корректным, но может не работать для остальной части вашего приложения.
- Приведите
{}
, как вы делаете сейчас. Это работает, но вы фактически лжете компилятору заранее (в начале, это действительно не полный FormErrors), а затем исправляете его позже, прежде чем что-то действительно сломается.
Какой из них вы хотите Выбор зависит от вашего варианта использования, но я думаю, что это основные варианты.