【问题标题】:Update value in object with a variable property name in Typescript在 Typescript 中使用变量属性名称更新对象中的值
【发布时间】:2022-11-03 00:18:33
【问题描述】:

我有这个方法:

updateDate(row: TaskItem, column: keyof TaskItem, date: string) {
  row[column] = date;
}

TaskItem 看起来像这样:

export interface TaskItem {
  id: number,
  myDate: string
}

我希望能够这样称呼它:

updateDate(rowItem, 'myDate', '2022-02-20');

但是,TS 不喜欢它:

类型“字符串”不可分配给类型“从不”.ts(2322)

只要我将row: TaskItem 更改为row: any,它就会起作用,但我想更简洁。

【问题讨论】:

    标签: typescript


    【解决方案1】:

    这可以通过泛型很好地解决,以安全地处理任何对象类型,强制第二个参数只能是obj 的键,并且第三个参数强制与typeof obj[key] 的类型相同。

    function updateProp<TObj, K extends keyof TObj>(obj: TObj, key: K, value: TObj[K]) {
        obj[key] = value;
    }
    
    interface TaskItem {
        id: number,
        myDate: string
    }
    
    declare const rowItem: TaskItem;
    
    updateProp(rowItem, 'myDate', '2022-02-20');
    

    Playground Link

    【讨论】:

      【解决方案2】:

      您得到的错误是完全正确的,因为您的 updateDate 函数假定新值 (date) 是类型string。但是,您并没有指定要更新的确切字段,因此您在此处的冲突很小,因为即使新值是类型stringcolumn 仍有可能是 id (column: 'id' | 'myDate')不是typeof stringnumber

      要么你应该让这个函数updateDate负责只要用于更新 myDate 字段:

      function updateDate(row: TaskItem, date: string) {
        row.myDate = date
      }
      

      或添加条件以确保仅更新 myDate 字段:

      function updateDate(row: TaskItem, column: keyof TaskItem, date: string) {
        if (column === 'myDate') {
           row[column] = date
        }
      }
      

      Typescript playground

      【讨论】:

        猜你喜欢
        • 1970-01-01
        • 2011-11-29
        • 1970-01-01
        • 1970-01-01
        • 2013-01-29
        • 1970-01-01
        • 2013-11-23
        • 1970-01-01
        • 2021-08-21
        相关资源
        最近更新 更多