1

stripe form

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
5
  • Can you post errors or example for you problem? Commented Oct 12, 2019 at 17:40
  • @Oleg edited and included the typescript error Commented Oct 12, 2019 at 18:09
  • How did you define IState with dynamic keys? Commented Oct 12, 2019 at 18:12
  • I'm not using dynamic keys as I know for sure there are only 3 inputs, so I declared them statically in state. I'm wondering how I can use the element name returned by the onChange event to dynamically set the state based on which element was changed. Commented Oct 12, 2019 at 18:17
  • Loook at stackoverflow.com/questions/42090191/… Commented Oct 12, 2019 at 18:22

1 Answer 1

0

I’d say it’s not possible for typescript to infer that the key you are using will always be a ‘keyof’ the type of your state, as you are concatenating two strings together - that it why it is showing [x: string] in the error message. You could rework elementType so that it’s type is keyof(YourStateTypesName), and then you would not need to do the string concatenation and the compiler would be happy. Or you could just assign your concatenation to a variable and cast it to keyof(YourStateTypesName) and it will also satisfy the compiler.

Sign up to request clarification or add additional context in comments.

Comments

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.