如何删除一个属性从一个对象在Typescript没有一个'删除'操作符的操作数必须是可选的错误?

pprl5pva  于 2023-03-04  发布在  TypeScript
关注(0)|答案(5)|浏览(350)

我试着在这里阅读如何从对象中删除属性:How do I remove a property from a JavaScript object?
它应该使用delete,我这样尝试

const eventData = {...myEvent}; // myEvent is an instance of my `Event` class
delete eventData.coordinate; // I have error in here

但我有这样的错误

“delete”运算符的操作数必须是可选的。ts(2790)
然后我读到这个Typescript does not infer about delete operator and spread operator?
它似乎是通过使用以下命令更改我的tsconfig.json文件来消除该错误的

{
  "compilerOptions": {
    ...
     "strictNullChecks": false, 
    }
    ...
}

但是如果我实现了这个,我将不再进行空值检查
那么如何在没有'delete'操作符的操作数的情况下从Typescript中的对象中删除属性一定是可选错误?

dzjeubhm

dzjeubhm1#

Typescript会警告你违反契约(对象将不再具有required属性)。一种可能的方法是在克隆对象时忽略该属性:

const myEvent = {
    coordinate: 1,
    foo: 'foo',
    bar: true
};

const { coordinate, ...eventData } = myEvent;
// eventData is of type { foo: string; bar: boolean; }

Playground
delete的操作数必须是可选的。在strictNullChecks中使用delete运算符时,操作数必须是anyunknownnever或可选的(因为它在类型中包含undefined)。否则,使用delete运算符是错误的。
文件

gg0vcinb

gg0vcinb2#

如果属性是可选的,则可以删除

interface OptionalCoordinate {
   coordinate?
}

const eventData: OptionalCoordinate = {...myEvent}; // myEvent is an instance of my `Event` class
// ok to delete
delete eventData.coordinate;
mwkjh3gx

mwkjh3gx3#

就我个人而言,我利用泛型创建了一个特定的函数,并且它运行得很好!

const removeAttrFromObject = <O extends object, A extends keyof O>(
  object: O,
  attr: A
): Omit<O, A> => {
  const newObject = { ...object }

  if (attr in newObject) {
    delete newObject[attr]
  }

  return newObject
}

两个泛型OA创造了所有的奇迹,尤其是A泛型:extends keyof O表示“第二个参数必须是来自对象的属性”。
然后在函数内部,TypeScript确定attr是来自object的属性。我使用attr in newObject if语句进行了双重检查,以确保在运行时一切正常。这只是纯粹的防御性编程。
这里的const newObject = { ...object }是为了确保我们不会修改作为arg传递的引用,而是返回一个新的引用,这是我过去函数式编程的一些遗留物。
现在我们试试这个函数:

const test = removeAttrFromObject({ a: 1, b: 2 }, 'a')
// returns as type `Omit<{a: 1, b: 2}, 'a'>` which equals `{a: 1}`

const test2 = removeAttrFromObject({ a: 1, b: 2 }, 'c') 
// TypeScript raise an error as `'c'` is not a key from the object passed
rqmkfv5c

rqmkfv5c4#

这个错误告诉您的是coordinate不是该对象的可选属性(也就是说,它可以是未定义的),您正在尝试删除它。
如果它是可选的,您可以将其删除

coordinate?: FirebaseFirestore.Geopoint

它似乎是在4.0版本之后引入的,你可以在here上阅读更多关于它的信息。

6bc51xsx

6bc51xsx5#

删除属性的另一种方法:

/* eslint-disable @typescript-eslint/no-explicit-any */
delete (eventData as any).coordinate;

相关问题