React + TypeScript установленное состояние с динамическими именами ключей - PullRequest
1 голос
/ 12 октября 2019

stripe form

Чтобы проверить форму оформления Stripe, я пытаюсь динамически сохранять события изменения из формы в состоянии. Событие содержит elementType , который является 'cardNumber', 'cardExpiry' или 'cardCvc'.

Я настроил состояние для хранения событий следующим образом:

interface State {
  cardCvcEvent: stripe.elements.ElementChangeResponse | null;
  cardExpiryEvent: stripe.elements.ElementChangeResponse | null;
  cardNumberEvent: stripe.elements.ElementChangeResponse | null;
}

У меня работают обновления состояния, но я не удовлетворен. Я хочу справиться с этим, используя динамическое назначение клавиш в один лайнер. Вот мое рабочее обновление с закомментированной нужной строкой:

public handleChange(e: stripe.elements.ElementChangeResponse) {
  // todo: git gud
  // should be able to figure out typescript so this line works:
  // this.setState({[e.elementType + 'Event']: e});

  switch (e.elementType) {
    case 'cardCvc': {
      this.setState({cardCvcEvent: e});
      break;
    }
    case 'cardExpiry': {
      this.setState({cardExpiryEvent: e});
      break;
    }
    case 'cardNumber': {
      this.setState({cardNumberEvent: e});
      break;
    }
  }
}

Я нашел это, которое, кажется, указывает в правильном направлении, но все еще не работает для моего случая:

Ввод ключей динамического объекта с помощью TS

Любые мысли по этому поводу приветствуются.

Редактировать: Вывод ошибки машинописного текста

Argument of type '{ [x: string]: ElementChangeResponse; }' is not assignable to parameter of type 'State | ((prevState: Readonly<State>, props: Readonly<Props>) => State | Pick<State, "cardCvcEvent" | "cardExpiryEvent" | "cardNumberEvent"> | null) | Pick<State, "cardCvcEvent" | ... 1 more ... | "cardNumberEvent"> | null'.
  Type '{ [x: string]: ElementChangeResponse; }' is missing the following properties from type 'Pick<State, "cardCvcEvent" | "cardExpiryEvent" | "cardNumberEvent">': cardCvcEvent, cardExpiryEvent, cardNumberEvent

1 Ответ

0 голосов
/ 12 октября 2019

Я бы сказал, что для машинописного текста невозможно сделать вывод, что используемый вами ключ всегда будет «ключом» типа вашего состояния, так как вы объединяете две строки вместе - именно поэтому он показывает [x:строка] в сообщении об ошибке. Вы можете переделать elementType так, чтобы его тип был keyof (YourStateTypesName), и тогда вам не нужно было бы выполнять конкатенацию строк, и компилятор был бы счастлив. Или вы можете просто присвоить свою конкатенацию переменной и привести ее к keyof (YourStateTypesName), и он также удовлетворит компилятор.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...