【问题标题】:React + TypeScript set state with dynamic key namesReact + TypeScript 使用动态键名设置状态
【发布时间】:2020-02-09 21:26:48
【问题描述】:

为了验证 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;
    }
  }
}

我发现了这个,它似乎指向了正确的方向,但它仍然不适用于我的情况:

Typing Dynamic Object Keys With 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

【问题讨论】:

  • 你可以为你的问题发布错误或示例吗?
  • @Oleg 编辑并包含了打字稿错误
  • 你是如何用动态键定义 IState 的?
  • 我没有使用动态键,因为我知道只有 3 个输入,所以我将它们静态声明为状态。我想知道如何使用 onChange 事件返回的元素名称来根据更改的元素动态设置状态。

标签: reactjs typescript


【解决方案1】:

我想说打字稿不可能推断出您使用的密钥将始终是您的状态类型的“keyof”,因为您将两个字符串连接在一起 - 这就是它显示 [x: string] 在错误消息中。您可以重新设计 elementType,使其类型为 keyof(YourStateTypesName),然后您不需要进行字符串连接,编译器会很高兴。或者您可以将您的串联分配给一个变量并将其转换为 keyof(YourStateTypesName) ,它也会满足编译器的要求。

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 2018-12-19
    • 1970-01-01
    • 2019-08-23
    • 1970-01-01
    • 1970-01-01
    • 2019-04-02
    • 2020-05-06
    • 2020-08-12
    相关资源
    最近更新 更多