0

I have function that help me get array of images with theirs nested paths as in title, value. But I have problems with typing, since still need to use any.

Is there any way to type my code properly to avoid any? You can edit any types in the code below as you like.

const testIcons = {
  large: {
    image_title1: 'some image 1',
    action: {
      image_title2: 'some image 2',
      light: {
        image_title3: 'some image 3',
      },
    },
  },
}

type BaseIconPath = {
  [key: string]: BaseIconPath | string
}

// TS doesn't happy here so I use any(
const getNestedIcons = (basePath: any, icon: string): any => {
  return Object.keys(basePath).map((nestedIcon) => {
    if (typeof basePath[nestedIcon] === 'object') {
      return getNestedIcons(basePath[nestedIcon], `${icon}.${nestedIcon}`)
    }
    return { title: `${icon}.${nestedIcon}`, value: `${icon}.${nestedIcon}` }
  })
}

const getIconsListFromUiKit = (iconSize: keyof typeof testIcons): any => {
  const basePath: BaseIconPath = testIcons[iconSize]

  return Object.keys(basePath)
    .map((icon) => {
      // in case of nested icons
      if (typeof basePath[icon] === 'object') {
        return getNestedIcons(basePath[icon], icon)
      }

      return { title: icon, value: icon }
    })
    .flat(Infinity)
}

getIconsListFromUiKit('large')

TS playground link

1 Answer 1

1

The correct return type should be { title: string; value: string }[]. You should also use flatMap instead as it simplifies the code.

type NestedRecord<T> = { [key: string]: T | NestedRecord<T> };

const getNestedIcons = (basePath: NestedRecord<string>, icon: string): { title: string; value: string }[] => {
    return Object.keys(basePath).flatMap((nestedIcon) => {
        const value = basePath[nestedIcon];

        if (typeof value === "object") {
            return getNestedIcons(value, `${icon}.${nestedIcon}`);
        }

        return { title: `${icon}.${nestedIcon}`, value: `${icon}.${nestedIcon}` };
    });
};

const getIconsListFromUiKit = (iconSize: keyof typeof testIcons) => {
    const basePath: BaseIconPath = testIcons[iconSize];

    return Object.keys(basePath).flatMap((icon) => {
        const value = basePath[icon];

        if (typeof value === "object") {
            return getNestedIcons(value, icon);
        }

        return { title: icon, value: icon };
    });
};

Playground

Sign up to request clarification or add additional context in comments.

3 Comments

Nice, but still what we should use for path type instead of any?
@Ksenia Oh yeah, I corrected it now.
Thanks! You helped me to understand TS better

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.