Follow

Keep Up to Date with the Most Important News

By pressing the Subscribe button, you confirm that you have read and are agreeing to our Privacy Policy and Terms of Use
Contact

Typescript: do I have to check for array to get rid of TS7053 (string index to possible array element)

I have run into a situation where I believe obeying typescript checks produces slower code.

So, here’s my (oversimplified) function:

function test(data: { [key: string]: any } | any[]) {
  const x = Object.keys(data).reduce((res: { [key: string]: any }, name: string) => {
    const item = data[name];
    const key = item?.name || name;
    ...
  });
}

basically just converts either array or object into an object – when looked simplified like this. In reality it also makes sure that items are of correct class type.

MEDevel.com: Open-source for Healthcare and Education

Collecting and validating open-source software for healthcare, education, enterprise, development, medical imaging, medical records, and digital pathology.

Visit Medevel

Anyway, the data[name] line produces a TS7053, because – if data is the array – accessor should be a Number.

The solution to typescript warning is to rewrite the line like this:

const item = data instanceof Array ? data[Number(name)] : data[name];

However, I believe this solution is slower than implicit type coercion that happened before for instances where the parameter was an array. It first checks for type, branches and only then does the explicit type conversion and finally accesses the item.

I realize that in case of array, a much more proper solution would be to simply use Array.forEach, but that would require a function extraction to not duplicate the code in question, which is only three lines in its entirety. The intent is just to index the items by their name property for faster access.

Is there a better way to make TypeScript checker happy?

>Solution :

You could use Object.entries() instead of Object.keys(). This saves you from having to do the value lookup and fixes your type problem at the same time:

function test(data: { [key: string]: any } | any[]) {
  return Object.entries(data).reduce((a: { [key: string]: any }, [k, v]) => {
    a[v?.name || k] = v;
    return a;
  }, {});
}

Playground link

Add a comment

Leave a Reply

Keep Up to Date with the Most Important News

By pressing the Subscribe button, you confirm that you have read and are agreeing to our Privacy Policy and Terms of Use

Discover more from Dev solutions

Subscribe now to keep reading and get access to the full archive.

Continue reading