Основная причина
Это вызвано известной проблемой с TypeScript, когда имена вычисляемых свойств, состоящие из объединения литералов , расширены.
В handleChange
тип field
расширен с 'title' | 'description'
до string
, что приводит к сбою this.setState
из-за способа определения this.setState
.
Ниже приведено упрощенное определение setState
:
function setState<K extends keyof State>(s: Pick<State, K>): void {
console.log(s);
}
. При применении этого определения к handleChange
, K
выше становится 'title' | 'description'
, а параметр s
становится Pick<State, 'title' | 'description'>
, чтопо существу эквивалентен интерфейсу State
.
Итак, учитывая, что наш field
был расширен до string
и this.setState
в этом контексте принимает State
, мы получим ошибку, которую вымы видим, как мы вызываем this.setState
со следующим типом:
{ [x: string]: V }
, который нельзя назначить на State
, так как в нем отсутствуют обязательные параметры title
и description
.
Решение
Лучше всего здесь использовать утверждение типа , чтобы отключить ошибку, пока основнойпроверка типа.Обновленное определение приведено ниже:
let handleChange: ChangeHandler<State> = field => value =>
setState({ [field]: value } as unknown as State);
let x = handleChange('title');
x('test'); // OK
x(50); // Error: should be string
См. ссылку на эту игровую площадку , содержащую приведенный выше код.
См. обсуждение по этому конкретному вопросуошибка в DefinitiveTyped для альтернативных решений / подходов.