打字稿不推断通用对象的值
Posted
技术标签:
【中文标题】打字稿不推断通用对象的值【英文标题】:Typescript doesn't infer value of generic object 【发布时间】:2020-08-27 11:49:48 【问题描述】:考虑一下这个函数,它遍历提供的对象的键并将每个键设置为一个数字,然后返回该对象。出于某种原因,打字稿没有推断出 obj[key] 值是一个数字,我收到以下错误:
类型 '1' 不可分配给类型 'T[keyof T]'.ts(2322)
有谁知道如何解决这个问题?参数应始终为Record<string, number>
。
function setObjKeysToOne<T extends Record<string, number>>(obj: T)
(Object.keys(obj) as Array<keyof typeof obj>).forEach((key) =>
obj[key] = 1; // Type '1' is not assignable to type 'T[keyof T]'.ts(2322)
);
return obj;
【问题讨论】:
你确定你需要它通用吗? Playground 是的,我确实需要它,这不是真实世界的代码,我创建它是为了说明问题,实际上我需要一个泛型。 如果没有更多的用例,我会警惕这种代码。该签名不需要是通用的,如果T
比Record<string, number>
窄,例如a: 123, b: 456
属性为numeric literal types,那么您想要编译器抱怨设置其属性为1
。
@jcalz 我在这里看到了问题,但我只想确保值是数字,我不在乎它们是否是文字。我想类型转换是这里唯一的方法。在实际代码中,当满足某个条件时,我将值设置为0
,如果这更有意义的话,这是一个人为的例子。
【参考方案1】:
您可以在分配期间强制转换 obj,例如
function setObjKeysToOne<T extends Record<string, number>>(obj: T)
Object.keys(obj).forEach((key) =>
(obj as Record<string, number>)[key] = 1;
);
return obj;
在 github 上有一个与 explanation 相关的问题,为什么 typescript 会这样。
【讨论】:
以上是关于打字稿不推断通用对象的值的主要内容,如果未能解决你的问题,请参考以下文章