从3.8版开始。+打字稿已将具有不同类型的多个属性的结果类型更改为并集,现在将其计算为never
。如果您将遍历对象的属性并尝试执行与它们相似的操作,则会出现Type {some_type} is not assignable to type never
错误
简单示例
interface Multitypes {
name: string;
age: number;
}
type MultitypesKey = keyof Multitypes;
const updateValues = (item: Multitypes, item2: Multitypes, keys: MultitypesKey[] = []) => {
for (let i = 0; i < keys.length; i++) {
item[keys[i]] = item2[keys[i]]; // this line will show an error
}
};
关于如何避免该错误并重构上面的代码的任何建议?
这里您需要密钥的通用参数:
const clearValues = <K extends MultitypesKey>(
item: Multitypes,
item2: Multitypes,
keys: K[] = []
) => {
for (let i = 0; i < keys.length; i++) {
item[keys[i]] = item2[keys[i]];
}
};
问题是Typescript必须能够推断出仅MultitypesKey[]
的更具体的类型。但是在您的原始代码中,keys
为MultitypesKey[]
,每次使用它时,打字稿都不知道其相同的数组。需要特别知道各个索引具有具体类型。
通过使参数通用,Typescript知道keys
是type K[]
,并且K
是从传入的内容中推断出来的。因此,现在可以确定,每次在keys
上使用相同的索引时,您都会知道返回相同的类型。
这里是您原始代码的jsfiddle示例。您可以运行它以查看遇到的第一个错误:https://jsfiddle.net/a9gd23jy/
该行抛出错误:
type MultitypesKey = keyof Multitypes;
此行引发错误Uncaught ReferenceError: Multitypes is not defined
。
对于任何类型T,T的键是T的已知公共属性名称的并集
您使用它的方式是获取表示其所有属性键的类型的表示形式,该类型表示为字符串文字类型的并集。这似乎不起作用,但是我看过使用该方法的教程,所以也许以前它是这样工作的,但在较新的版本中却没有。
无论如何,这是一个可行的示例,但进行了一些小的更改以使其按您期望的我认为:https://jsfiddle.net/a9gd23jy/3/
摆脱type MultitypesKey = keyof Multitypes;
,因为它不是必需的,似乎会导致错误。然后只需对updateValues
函数进行少量更改即可使用keyof
:
function updateValues<Key extends keyof Multitypes>(item: Multitypes, item2: Multitypes, keys: Key[] = []) {
for (let i = 0; i < keys.length; i++) {
item[keys[i]] = item2[keys[i]];
}
};