javascript - typescript :如何在 Object.entries().forEach([key,value]) => 中正确键入键和值参数

标签 javascript typescript typescript-typings

我得到了一个具有特定键/值参数的对象,我想用 Object 的 entries() 方法和 Array 的 forEach() 方法对其进行迭代。但是我不明白如何输入此配置以避免 typescript 错误:

type objType = {
  prop1: number | undefined;
  prop2: number | undefined;
  prop3: number | undefined;
};

const obj: objType = {
  prop1: 2,
  prop2: 0,
  prop3: undefined,
};

//1st attempt
Object.entries(obj).forEach(([key, value]) => {
  if (value === undefined || value < 5) obj[key] = 5;
});

//2nd attempt
Object.entries(obj).forEach(
  ([key, value]: [keyof objType, number | undefined]) => {
    if (value === undefined || value < 5) obj[key] = 5;
  }
);

在第一次尝试中,我让 typescript 推断 key(→ string)和 value(→ number|undefined )。但在这种情况下,我在执行 obj[key] 时遇到错误:

Element implicitly has an 'any' type because expression of type 'string' can't be used to index type 'objType'. No index signature with a parameter of type 'string' was found on type 'objType'.

在第二次尝试中,我使用 keyof 运算符强制 key 的类型对应于 obj 的键,但是这个类型定义不是允许,我收到以下消息:

Argument of type '([key, value]: [keyof objType, number | undefined]) => void' is not assignable to parameter of type '(value: [string, number | undefined], index: number, array: [string, number | undefined][]) => void'. Types of parameters '__0' and 'value' are incompatible. Type '[string, number | undefined]' is not assignable to type '[keyof objType, number | undefined]'. Type at position 0 in source is not compatible with type at position 0 in target. Type 'string' is not assignable to type 'keyof objType'.

我理解第一次尝试失败,但第二次失败。为什么 TS 认为我想将字符串分配给字符串枚举,我猜想做相反的事情......?

如何正确键入此配置?

最佳答案

为什么

首先我们需要了解为什么会这样: 让我们来看一个最简单的例子:

const obj = {a: 1};
Object.keys(obj).forEach((key:keyof typeof obj)=> ''); // fails because Type 'string' is not assignable to type '"a"'

出现这种情况,是因为TS不能保证对象中没有其他键。因此,它不能保证 key 将ONLY 'a'。

在您的情况下,这意味着 TS 无法确保 obj[key] 的值是数字。它可能是任何东西,因此 TS 会抛出一个错误。

Example

选项#1

处理此问题的一种方法是强制 TS 使用您的类型:

//1st attempt
Object.entries(obj).forEach(([key, value]) => {
  if (value === undefined || value < 5) obj[key as keyof typeof obj] = 5;
});

//2nd attempt
Object.entries(obj).forEach(
  ([key, value]) => {
    if (value === undefined || value < 5) obj[key as keyof typeof obj] = 5;
  }
);

如果您绝对确定不会出现额外的键,这没关系。

选项#2

另一种方法是将类型重新设计为更通用的类型:

type objType = {
    prop1: number | undefined;
    prop2: number | undefined;
    prop3: number | undefined;
}

const obj: Record<string, number | undefined> = {
    prop1: 2,
    prop2: 0,
    prop3: undefined,
};

//1st attempt
Object.entries(obj).forEach(([key, value]) => {
    if (value === undefined || value < 5) obj[key] = 5;
});

//2nd attempt
Object.entries(obj).forEach(
    ([key, value]) => {
        if (value === undefined || value < 5) obj[key] = 5;
    }
);

在上面的代码中,我们明确声明我们允许任何字符串键。

check一些额外的细节

关于javascript - typescript :如何在 Object.entries().forEach([key,value]) => 中正确键入键和值参数,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/70420283/

相关文章:

typescript - 如何使用 Type Script 中的反射获取实现某个基类的子类?

基于可选参数存在而不使用函数重载的 typescript 函数返回类型

javascript - Jquery attr 方法在 'onMouseEnter' 上不起作用

javascript - 从 XHR/Ajax 请求返回 javascript 的实际用例?

node.js - Typescript 编译器选择错误的重载

javascript - lodash _.get 的类型安全版本 - 有条件地解构数组类型

Typescript:React Native useRef 给出错误 "Object is possibly null"

javascript - 如何在不刷新页面的情况下重复此代码?设置间隔?其他?

Javascript - 用连字符替换连续的空格

javascript - Angular递归创建动态组件