hur man tar bort en egenskap från ett objekt i Typescript utan felet 'operanden till en 'delete'-operator måste vara valfri'?


Jag har försökt läsa hur man tar bort en egenskap från ett objekt här: Hur tar jag bort en egenskap från ett JavaScript-objekt?

det borde använda delete, jag försöker på det här sättet

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

men jag har ett fel som detta

Operandet till en 'delete'-operator måste vara valfritt.ts(2790)

och sedan läste jag detta: Typescript härleder inte om delete-operatorn och spread-operatorn?

det verkar som att ta bort det felet är genom att ändra min tsconfig.json-fil med

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

men om jag implementerar detta kommer jag inte längre att ha nollkontroll

så hur tar man bort en egenskap från ett objekt i Typescript utan felet att operandet för en 'delete'-operator måste vara valfri?

Svar #1

Typescript varnar dig om att bryta kontraktet (objektet kommer inte längre att ha den nödvändiga egenskapen). Ett av de möjliga sätten skulle vara att utelämna egenskapen när du klonar objektet:

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

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

Lekplats


Operander för delete måste vara valfria. När man använder delete-operatorn med strictNullChecks måste operanden vara any, unknown, never eller vara valfri (d.v.s. innehålla undefined i typen). Annars är användning av delete-operatorn ett fel.

Dokument

Svar #2

Personligen skapade jag en specifik funktion som utnyttjar generics, och det fungerade bra!

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
}

De två generiska O och A gör all magi, särskilt den generiska A: extends keyof O säger "den andra parametern måste vara en egenskap från objektet".

Sedan, inne i funktionen, vet TypeScript säkert att attr är ett attribut från object. Jag dubbelkollar med attr in newObject-if-satsen för att vara säker på att allt också är bra vid körning. Bara ren defensiv programmering.

Koden const newObject={ ...object } är här för att försäkra oss om att vi inte ändrar referensen som skickats som argument, utan istället returnerar en ny referens. Det är lite rester från mina gamla dagar med funktionell programmering.

Nu om vi provar funktionen:

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

Relaterade artiklar