首页 > 解决方案 > 使用 typecirpt 对对象进行部分更新

问题描述

我想要实现的是创建一个实用程序函数,该函数将实例和对象除外,并使用提供的输入字段值更新实例。这是效用函数:

function updateEntity<T, K extends keyof T>(
    entity: T,
    updateInput: { [key in K]: T[K] },
  ): void {
    return Object.keys(updateInput).forEach((key) => {
      entity[key as K] = updateInput[key as K];
    });
}

在这里我有一个实例和一个更新界面:

class Animal {
  name: string = 'no name';
  isMale: boolean = false;
}

type Input = Partial<{
  name: string;
}>;

const input: Input = {
  name: 'str'
};

const cat = new Animal();

updateEntity(cat, input); // input is an error

我收到以下错误:

Argument of type 'Partial<{ name: string; }>' is not assignable to parameter of type '{ name: string; }'.
  Types of property 'name' are incompatible.
    Type 'string | undefined' is not assignable to type 'string'.
      Type 'undefined' is not assignable to type 'string'.(2345)

我不认为我完全理解错误信息。我的意图是使用提供的输入部分更新原始实例。

输入必须是原始实例的子集(没有额外的字段)。

这是游乐场的链接:link

我错过了什么?

标签: typescript

解决方案


使用非空断言。当您将鼠标悬停在updateInput参数上时,其类型将为,{ [key in K]?: T[K] | undefined }因为缺少的字段将为undefined. TypeScript 仍然相信updateInput[key]can beundefined而不是T[K],但我们很确定updateInput[key]can only be of type T[K]

function updateEntity<T, K extends keyof T>(
  entity: T,
  updateInput: { [key in K]?: T[K] },
): void {
  for (const key in updateInput) {
    entity[key] = updateInput[key]!;
  }
}

推荐阅读