首页
学习
活动
专区
工具
TVP
发布
社区首页 >问答首页 >TypeScript中具有混合类型属性的对象的动态赋值

TypeScript中具有混合类型属性的对象的动态赋值
EN

Stack Overflow用户
提问于 2022-03-30 18:22:09
回答 1查看 1.1K关注 0票数 0

假设我有一个具有不同类型的属性的对象,并且我想给一个动态标识的属性分配一个动态值。这在JavaScript中非常好,但是我如何在TypeScript中做到这一点,消除not assignable to type 'never' TS(2322)错误,理想情况下不使用any

示例代码(操场在这里):

代码语言:javascript
复制
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”。在这种情况下是什么?

EN

回答 1

Stack Overflow用户

发布于 2022-03-30 18:54:13

解决方案是在这样的类型签名中使用双泛型,使其他所有内容保持不变:

代码语言:javascript
复制
const myFunctionGeneric = function<K extends keyof Film, V extends Film[K]>(
    film: Film,
    filmPropertyName: K,
    newValue: V
) 

修改后的操场这里

票数 0
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/71682263

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档