【问题标题】:Function to set the state of a nested object with argument variable as key以参数变量为键设置嵌套对象状态的函数
【发布时间】:2021-01-24 13:15:42
【问题描述】:

我想用函数updateDatas 更新对象状态。我将key、可能的subKeyvalue 作为该函数的参数传递。

interface Datas {
  code: number;
  item1: Item;
}

interface Item {
  id: number;
  name: string;
}

const [datas, setDatas] = useState({
  code: 42,
  item1: {
    id: 1,
    name: 'foo'
  }
});

function updateDatas(key: string, subKey: string, value: any) {
  if (subKey) {
    setDatas({...datas, key: {...datas.key, subKey: value}});
  } else {
    setDatas({...datas, key: value});
  }
}

updateDatas('code', 23);
updateDatas('item1', 'name', 'bar');

但它不起作用,我有这个 Typescript 错误:

'{ key: any; 类型的参数代码:号码; item1:项目; }' 不可分配给“SetStateAction”类型的参数。 对象字面量只能指定已知属性,而 'key' 不存在于类型 'SetStateAction'.ts(2345)

【问题讨论】:

  • 我认为您必须将 key 和 subKey 括在方括号中 setDatas({...datas, [key]: {...datas.key, [subKey]: value}});

标签: reactjs typescript setstate


【解决方案1】:

您正在尝试更新密钥subKey,而不是使用变量subKey 作为字符串的密钥。与key 相同。执行以下操作:

function updateDatas(key: string, subKey: string, value: any) {
  if (subKey) {
    setDatas({...datas, [key]: {...datas[key] as Item, [subKey]: value}});
  } else {
    setDatas({...datas, [key]: value});
  }
}

无论如何,您应该在接口之间存在一些不一致,因为key 的类型是string 而不是keysof Datas,并且与subKey (keysof Item) 相同。

function updateDatas(key: keysof Datas, subKey: keysof Item, value: any) {
  if (subKey) {
    setDatas({...datas, [key]: {...datas[key], [subKey]: value}});
  } else {
    setDatas({...datas, [key]: value});
  }
}

编辑:与值相同,因为在您的界面中,您希望该值是其他东西而不是any。您应该寻找解决方法。

【讨论】:

  • ...datas.key 给出 ts 错误:Property 'key' does not exist on type 'Datas'....datas[key] 也不行。
  • Spread types may only be created from object types. ts(2698)
  • 哦,是的,因为您应该更好地键入函数的参数,因为它可以是任何 string 键,因此 TS 不知道 datas[key] 是否是要传播的对象,因为即 @ 987654338@ 是42。请检查我的回复
  • 我进行了更改(keysof 对我不起作用,但 keyof 是的):function updateDatas(key: keyof Datas, subKey: keyof Item, value: string | number)datas[key] 仍然不起作用
  • 该值可能是string | number | Item 类型,但仍然不是很好的类型。我会尝试另一种方法,而不是将所有这些都包含在一个函数中。我不知道您的用例,但可能是其他方式。如果合适,请考虑创建另一个问题并将答案标记为正确
猜你喜欢
  • 2020-11-02
  • 2019-02-22
  • 1970-01-01
  • 2016-04-29
  • 1970-01-01
  • 2018-12-28
  • 1970-01-01
  • 2022-07-07
  • 2021-02-12
相关资源
最近更新 更多