Arthur Costa
Arthur Costa

Reputation: 1549

How to give a custom type to an array key that is obtained by Object.values in Typescript?

Code: https://codesandbox.io/s/zealous-morning-3q6gm?file=/src/App.tsx

The error:

Argument of type '(key: Fiat) => JSX.Element' is not assignable to parameter of type '(value: string, index: number, array: string[]) => Element'. Types of parameters 'key' and 'value' are incompatible. Type 'string' is not assignable to type 'Fiat'.

What I'm trying to achieve: The quote expects a key of the type FIAT. Thus, when I am mapping I want to add the keys as FIAT type and not just a string. Is that even possible? If yes, how could I achieve that?

Upvotes: 0

Views: 527

Answers (2)

Shyam Pillai
Shyam Pillai

Reputation: 351

One option is to set the type of Object.keys(accounts) like so:

(Object.keys(accounts) as Array<keyof typeof accounts>

So your entire code then becomes :

export default function App() {
  const [accounts] = React.useState<AccountsMap>({
    "USD": 100,
    "AUD": 10,
    "BRL": 50
  });

  const [quote] = React.useState<Quote>({ USD: 2.5, AUD: 1.9, BRL: 5 });
  return (
    <div className="App">
      <h1>Hello CodeSandbox</h1>
      <h2>Start editing to see some magic happen!</h2>

      {(Object.keys(accounts) as Array<keyof typeof accounts>).map((key: Fiat) => (
        <p> {quote[key]} </p>
      ))}

      {(Object.keys(accounts) as Array<keyof typeof accounts>).map((key: Fiat) => (
        <p> {quote[key]} </p>
      ))}
    </div>
  );
}

Here we're suggesting to typescript to consider the array of strings returned by Object.keys(accounts) as the key type of typeof accounts, which in this case will be of type Fiat .

Upvotes: 3

Arthur Costa
Arthur Costa

Reputation: 1549

Adding that remove the code below removed the Typescript error. However, I am not sure what this is doing and if it's the right way to fix the issue.

{Object.keys(accounts).map((key: string) => (
    <p> {quote[key as Fiat]} </p>
))}

Upvotes: 0

Related Questions