javascript - Ravnanje ugniježđenih objekata bez TS pogreške


Radim na obrascu za uređivanje za moju tvrtku i netko iz mog tima odlučio je promijeniti oblikovanje povratne vrijednosti našeg API-ja bez konzultiranja ostatka tima i sada pokušavamo sustići.

Budući da API koji pozivamo mora poslati vrijednost natrag u bazu podataka nije postavljen za ugniježđene objekte, moram ga izravnati kako bih mogao manipulirati vrijednostima i poslati ih.

Evo nove ugniježdene strukture

    {
       "status": 1, 
       "data" : {
            "name": "Tank",
            "dimensions": "2.0 x 2.5 x 4.0"
       }
    }

i trebam to pretvoriti natrag u nešto ovako:

    {
       "status": 1, 
       "name": "Tank",
       "dimensions": "2.0 x 22.5 x 4.0"
    }

Našao sam više rješenja online, ali sva mi daju istu TypeScript pogrešku

"za (... u ...) izraze mora se filtrirati s if izrazom"

Također primjećujem da mnogi od njih ugrađuju ime prvog elementa ispred njegovog ugniježđenog elementa, ovako:

    {
       "status": 1, 
       "data.name": "Tank",
       "data.dimensions": "2.0 x 22.5 x 4.0"
    }

Može li mi netko pokazati kako prepisati ovu flatten funkciju tako da ukloni TS pogrešku i ne dodaje ime elementa prvog nivoa njegovim ugniježđenim elementima, ostavljajući mi jednostavan objekt jedne razine?

Evo moje funkcije za spljoštavanje:

const obj = values;

const flattenObj = (ob) => {
  // The object which contains the final result
  const result = {};
  // loop through the object "ob"
  for (const i in ob) {
      // We check the type of the i using typeof() function and recursively call the function again
      if ((typeof ob[i]) === 'object' && !Array.isArray(ob[i])) {
          const temp = flattenObj(ob[i]);
          for (const j in temp) {
              // Store temp in result
              result[i + '.' + j] = temp[j];
          }
      }
      // Else store ob[i] in result directly
      else {
          result[i] = ob[i];
      }
  }
  return result;
};

console.log(flattenObj(ob));

Odgovor #1

Mogao bi promijeniti

for (const i in ob) { .. }

to

for (const [i, obi] of Object.entries(ob)) { // use obi instead of ob[i] }

tako ti uopće ne diraš prototip stvari.

Odgovor #2

Probaj ovo:

  "status": 1, 
  "data" : {
    "name": "Tank",
    "dimensions": "2.0 x 2.5 x 4.0"
  }
};

const flattenObj = (ob: Record<string, unknown>) => {
  const result: Record<string, unknown> = {};
  for (const i in ob) {
      if (ob.hasOwnProperty(i)) {
        const val = ob[i];
        if (val && typeof val === 'object' && !Array.isArray(val)) {
          const temp = flattenObj(val as Record<string, unknown>);
          for (const j in temp) {
              result[i + '.' + j] = temp[j];
          }
        }
        else {
          result[i] = ob[i];
        }
      }
  }
  return result;
};

console.log(flattenObj(obj));

Igralište

Neke promjene u odnosu na vašu verziju:

  1. Ima .hasOwnProperty uvjetnu provjeru kako bi zadovoljio pravilo lintanja
  2. Provjerava je li ob[i] istinito, imajte na umu da typeof null === 'object'!
  3. Tipizira argument i vrijednost povratka kao Record<string, unknown>. Za stvarno dinamičke objekte (kao što je odgovor s API poziva) nećete znati tip. Ako suzite tip podataka na određenu šemu, vjerojatno biste mogli koristiti template literal tipove i generike kako biste dobili tip-pouzdaniji, specifičniji povratni rezultat. Još uvijek pokušavam to shvatiti.