Typescript error when trying to access object using dynamic key

Svgs/index.ts

export { default as Ok } from './Ok';
export { default as Close } from './Close';

SomeFile.tsx

import * as svgs from '../Icon/Svgs';

<div>
{React.createElement(svgs[prefixIconName], {
         size: prefixIconSize || Icon.Size.xxs,
 })}
</div>

here variable prefixIconName is a string.
its giving this compile time error

Element implicitly has an 'any' type because expression of type 'string' can't be used to index type 'typeof import("d:/code/src/components/Icon/Svgs/index")'.
  No index signature with a parameter of type 'string' was found on type 'typeof import("d:/code/src/components/Icon/Svgs/index")'.ts(7053)

trying to fix this by type casting as well as “any” but does not work.

They aren’t strings per se, they are keys. So when you try to

svgs[prefixIconName]

prefixIconName could be any string if its type is string (which is what it’s being inferred as). You have to ensure that prefixIconName will only be one of the keys of svgs – TS is correct here, but dynamic object access is normally a pain point when learning TS. After several years of using TS, I normally still have to Google for examples when I’m doing something similar to what you’re trying, it can be v annoying. But the error normally means {thing} isn’t structured ideally, and requires a bit more care in how {thing} is to be accessed.

You need to show a bit more code here re how you are trying to use them, as somefile.tsx doesn’t quite make sense atm – ie why are you not just importing the specific SVG you want? I realise there’ll be a reason but can’t tell atm: there are a number of different ways you could approach this, but need a more realistic example.

But to immediately fix it’s not any you cast to, it’s keyof typeof svgs: you need the hint to TS to be more specific, not more general. If you say it’s any, then you’re saying the key could be a boolean or null or undefined or whatever, something it can’t possibly be.

direct importing any specific svg is not possible since someFile.tsx is getting
prefixIconName as prop and then using it to import an svg file dynamically.
I am going through this code for the first time and this way of importing file is also new to me.

Icon/Svgs/index.ts

export { default as Laptop } from './Laptop';
export { default as Ok } from './Ok';
export { default as Close } from './Close';
export { default as Eye } from './Eye';
export { default as HidePassword } from './HidePassword';
export { default as Error } from './Error';

Every Svg file looks like this
Close.tsx

export default class Close extends Icon {
    static displayName = 'Close';
    constructor(props: IProps) {
      super(props);
      this.name = 'Close';
    }
    // eslint-disable-next-line class-methods-use-this
    getSvgDefinitions(): JSX.Element {
      // eslint-disable-next-line react/react-in-jsx-scope
      return (<defs />);
    }
    // eslint-disable-next-line class-methods-use-this
    getSvgGnodes(): JSX.Element {
      return (
        <g>
          <path .903 18.743 45.275 18.743s32.766-6.255 45.275-18.764l402.697-402.692 402.675 402.692c12.509 12.509 28.903 18.764 45.275 18.764s32.766-6.255 45.275-18.764c25.018-24.997 25.018-65.557 0-90.554l-402.675-402.671z" />
        </g>
      );
    }
}

I have also faced same issue but was able to fix it somehow but in the above case no workaround.

plz let me know if you need any more file/code.

somehow but in the above case no workaround.

This topic was automatically closed 182 days after the last reply. New replies are no longer allowed.