假设我有一个具有不同类型的属性的对象,并且我想给一个动态标识的属性分配一个动态值。这在JavaScript中非常好,但是我如何在TypeScript中做到这一点,消除not assignable to type 'never'
TS(2322)错误,理想情况下不使用any
示例代码(操场在这里):
interface Film {
name : string;
durationInSeconds : number;
}
const myFunction = function(
film: Film,
filmPropertyName: keyof Film,
newValue: string | number
) {
let value = film[filmPropertyName];
console.log('Existing value:', value); //value is of type `string | number`, inferred in prior line
//That means that on read, film[filmPropertyName] is of type `string | number` as expected.
//However, on write, it's of type `never.`
film[filmPropertyName] = newValue; //not assignable to type 'never'.ts(2322)
value = newValue; //works just fine with both sides as `string | number`
//Checking that types match seems like a sensible requirement but doesn't help:
if(typeof film[filmPropertyName] === typeof newValue) {
value = newValue; //works fine
film[filmPropertyName] = newValue; //same error as above
}
//even checking that both are a specific standard type doesn't help:
if(typeof film[filmPropertyName] === 'string' && typeof newValue === 'string') {
value = newValue; //works fine
film[filmPropertyName] = newValue; //same error as above
}
}
在这个很小的例子中,人们可能会建议删除类型组合,例如将durationInSeconds
设置为string
类型,并将newValue
param的类型更改为string
。虽然在这样一个很小的例子中,这可能是可以的,但在需要其他类型的更复杂的实际代码上,它不起作用。
对于其他遇到此问题的人,将film
参数的类型更改为any
满足此错误,但可能会触发其他错误,例如,如果film
或其属性在此函数的主体中传递给其他函数。
赋值之前的转换(例如(film as any)[filmPropertyName] = newValue
)使错误消失,可能至少应该在第一个排版条件下完成,但似乎正在放弃TypeScript的打字功能--添加any
注解和转换实际上并不像“TypeScript way”。在这种情况下是什么?
发布于 2022-03-30 18:54:13
解决方案是在这样的类型签名中使用双泛型,使其他所有内容保持不变:
const myFunctionGeneric = function<K extends keyof Film, V extends Film[K]>(
film: Film,
filmPropertyName: K,
newValue: V
)
修改后的操场这里。
https://stackoverflow.com/questions/71682263
复制相似问题