Home > Blockchain >  Typescript - Element implicitly has an 'any' type because expression of type 'any
Typescript - Element implicitly has an 'any' type because expression of type 'any

Time:11-01

in non .tsx pages we used to enum like this:

const enumUrl= {
  xxx: [BRAND],
  yyy: [BRAND],
};

In .tsx pages I would like to use enum. So I created:

  enum EnumUrl {
    xxx = "https://example.com/",
    yyy = "https://example.net"
  }

And in JSX:

  Visit <a href={EnumUrl[BRAND}} target="_blank" rel="noopener noreferrer">
    {EnumUrl[BRAND]}
  </a>

However it says:

Element implicitly has an 'any' type because expression of type 'any' can't be used to index type 'typeof EnumUrl'.ts(7053)

Then I read this possible solution: https://stackoverflow.com/a/41970976/1580094 and did the following:

  enum EnumUrl {
    xxx = "https://example.com/",
    yyy = "https://example.net"
  }

var url : EnumUrl = EnumUrl[BRAND as keyof typeof EnumUrl];

 ...   

 Visit <a href={url[BRAND}} target="_blank" rel="noopener noreferrer">
    {url[BRAND]}
  </a>

Console logs: console.log(url); // https://example.com/ console.log(url[BRAND]); // undefined console.log(BRAND); // xxx

But doing this way, the <a element completely disappears from DOM. No errors.

What am I doing wrong and how can I fix it?

CodePudding user response:

TL;DR an enum doesn't seem to be what you actually want here.

Oh I get that at first blush it seems like an enum: you have a set of URLs. And that set of URLs might actually be an enum, something like:

enum URLs {
  A = "www.foo.com",
  B = "www.bar.com"
}

The problem comes from how you are using the values. Because you are using your "enum" like a map: you're looking up values in it via keys dynamically provided. Javascript/Typescript already has a construct for this purpose (two in fact) so use it, with an enum:

enum Brands {
    'xxx',
    'yyy'
}

// Note that www.foo.com and www.bar.com could be in
// *another* enum, and you could use the URL_MAP to
// connect the two enums. But either way you'll want the
// object for dynamic lookups
const URL_MAP = {
    [Brands.xxx]: "www.foo.com",
    [Brands.yyy]: "www.bar.com",
};

function foo(brand: Brands) {
    return <a href={URL_MAP[brand]} />;
}

Playground

CodePudding user response:

Solution found. I just had to use {url}, because the BRAND was already applied in var url : EnumUrl = EnumUrl[BRAND as keyof typeof EnumUrl].

  • Related