0

We have a function such as below

export const objectUndefinedToNull = (obj) => {
  const apply = (o) => {
    Object.keys(o).forEach((key) => {
      const value = o[key];
      if (value === undefined) {
        o[key] = null;
      }
      if (value instanceof Array || value instanceof Object) {
        apply(value || {});
      }
    });
  };
  apply(obj);
  return obj;
};

I would like to replace all any and unknown types for more appropriate types. Is there any type that stands for any iterable types such as an array or object that can be iterated?

The.Wolfgang.Grimmer
  • 1,172
  • 2
  • 9
  • 32
  • Yes there is: `Iterable` – Silvermind May 14 '21 at 08:56
  • @Silvermind, Thanks, i didn't know there is such a type for this, but it doesn't seem to fit in my case because i want to be able to pass something like `Record` or `{ [key: string]: someType }` on `objectUndefinedToNull` object and `Iterable` has type mismatch to those mentioned types – The.Wolfgang.Grimmer May 14 '21 at 09:02
  • Does this answer your question? [Checking whether something is iterable](https://stackoverflow.com/questions/18884249/checking-whether-something-is-iterable) – Jofbr May 14 '21 at 09:14
  • not exactly, but i may be able to use it by rewriting the current function and just use type predicate or type guards to check for iterables – The.Wolfgang.Grimmer May 14 '21 at 09:24
  • This code doesn't actually work for object types such as `Record` does it? It's trying to set undefined object values to null, but `objectUndefinedToNull({ a: 1, b: undefined })` returns `{ 1: null, a: 1, b: undefined }`, which surely can't be what's intended. It only works for arrays as far as I can see. `objectUndefinedToNull([1, undefined])` returns `[1, null]` which looks better. – Rich N May 14 '21 at 10:03
  • @RichN , Yeah, thanks for noticing. I've already fixed the code snippet in the post. – The.Wolfgang.Grimmer May 16 '21 at 07:43

1 Answers1

2

You could define a IterableType class as follows and then use that in place of any and unknown.

class IterableType<T> implements Iterable<T>, Record<K,T>

Alternatively, keep using any and unknown as per your original code, but add some type checking to the function to check that it is a valid type (Array, record, etc).

Jofbr
  • 455
  • 3
  • 23
  • awesome, thanks for giving me an idea. I was currently playing around with this one and it seems like Typescript makes it hard to do so. Apparently, You have to implement your own `Symbol.iterator` – The.Wolfgang.Grimmer May 14 '21 at 09:18