我得到了一个具有特定键/值参数的对象,我想用 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 会抛出一个错误。
选项#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/