如何使用带有动态对象键的打字稿

Posted

技术标签:

【中文标题】如何使用带有动态对象键的打字稿【英文标题】:How to use typescript with dynamic object key 【发布时间】:2019-08-23 04:44:39 【问题描述】:

我有一个以天、小时和分钟记录时间的 State 对象。我这样定义我的状态:

type StateKeys = "days" | "hours" | "minutes";

type State = 
    [K in StateKeys]: number
;

稍后,我想根据控件中更改的值设置状态。共有三个控件,一个用于天,另一个用于小时,第三个用于分钟。我有一个连接到每个控件的处理函数。以下是该函数的摘录:

_onTimeComponentChange(e: any) 
    const name : StateKeys = e.currentTarget.name;
    const updatedValue = parseInt(e.currentTarget.value);
    this.setState(
        //@ts-ignore
        [name]: updatedValue, 
        () => 
            this.updateValue();
        
    )

我的目标是删除 //@tsignore 评论。如果我现在这样做,我会收到以下错误消息:

类型参数 ' [x: string]: number; ' 不可分配给 'State | 类型的参数(((prevState:只读,道具: 只读)=> 状态 |挑选)|挑选'。输入 ' [x: string]: number; ' 缺少 'Pick' 类型的以下属性:天、小时、 分钟

如何删除//@tsignorecomment 并满足打字稿的要求?

【问题讨论】:

如果类型计算属性类型是联合,Typescript 不能很好地处理计算属性。有时我只选择一个成员并使用类型断言const name = e.currentTarget.name as "days"; 看起来很愚蠢.. 但它就是这样.. 感谢@TitianCernicova-Dragomir。尝试满足 Typescript 对我来说绝对是一种黑魔法。 【参考方案1】:

如果不进行强制转换,肯定很难绕过这种类型的事情。您可以尝试遵循here 描述的模式:

updateState(key: StateKeys, value: string) 
  this.setState((prevState) => (
    ...prevState,
    [key]: value,
  ));

看起来像:

_onTimeComponentChange(e: any) 
  const name: StateKeys  = e.currentTarget.name
  const updatedValue = parseInt(e.currentTarget.value)
  this.setState(
    prevState => (
      ...prevState,
      [name]: updatedValue,
    ),
    () => 
    ,
  )

【讨论】:

以上是关于如何使用带有动态对象键的打字稿的主要内容,如果未能解决你的问题,请参考以下文章

带有动态键的打字稿通用函数

带有任意键的对象的打字稿接口? [复制]

打字稿如何定义对象,其中键的值取决于另一个键

具有定义值的打字稿动态对象键

打字稿:如何在对象更改时使用动态表行更新表

如何在打字稿中使用可能的字符串和数字索引确定对象的类型?