To validate a Stripe checkout form, I'm trying to dynamically store the change events from the form in state. The event contains elementType which is either 'cardNumber', 'cardExpiry', or 'cardCvc'.
I've set up state as follows to store the events:
interface State {
cardCvcEvent: stripe.elements.ElementChangeResponse | null;
cardExpiryEvent: stripe.elements.ElementChangeResponse | null;
cardNumberEvent: stripe.elements.ElementChangeResponse | null;
}
I have the state updates working, but I'm not satisfied. I want to handle this using dynamic key assignment in a one liner. Here's my working update with the desired line commented out:
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;
}
}
}
I found this, which seems to be pointing in the right direction but it still didn't work for my case:
Typing Dynamic Object Keys With TS
Any thoughts on this are appreciated.
Edit: The typescript error output
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