Tyler Pashigian
Tyler Pashigian

Reputation: 497

Pass associated value in Typescript object for certain enum keys

I am trying to iterate through an object where the keys are each case from an enum and the value is any type (using Typescript). This works fine when the value in the object is a predefined constant, but one of the values needs to use a provided string to generate a return object. Is there a way I can do this in Typescript? I will show a stripped down sample of what I am doing below.

Object Constants

export const injected = new InjectedConnector({
  supportedChainIds: [1, 3, 4, 5, 42],
});

export const walletconnect = new WalletConnectConnector({
  rpc: RPC_URLS,
  chainId: 1,
  bridge: 'https://bridge.walletconnect.org',
  qrcode: true,
});

export const walletlink = new WalletLinkConnector({
  url: RPC_URLS[1],
  appName: 'web3-react example',
  supportedChainIds: [1, 3, 4, 5, 42, 10, 137, 69, 420, 80001],
});

export const magic = (email: string) => {
  return new MagicConnector({
    apiKey: 'apiKey',
    chainId: 1,
    email: email,
  });
};

Enum and object to iterate over in front end

enum ConnectorNames {
  Injected = 'MetaMask',
  WalletConnect = 'WalletConnect',
  WalletLink = 'Coinbase Wallet',
  Magic = 'Email',
}

const connectorsByName: { [connectorName in ConnectorNames]: any } = {
  [ConnectorNames.Injected]: injected,
  [ConnectorNames.WalletConnect]: walletconnect,
  [ConnectorNames.WalletLink]: walletlink,
  // Would like to give magic an associated string value to pass into magic const above,
  // somehting like `magic([email protected])`
  [ConnectorNames.Magic]: magic,
};

Front End TSX

const TestComponent = () => {
  const [connector, setConnector] = useState<any>(null);
  const testString = 'Hello, World!';
  return (
    <>
      {Object.keys(connectorsByName).map((name) => {
        // Would like to pass in test string to the connector/name in some way, and have magic
        // consume it and the other 3 enum cases that dont need the associated value ignore it
        const currentConnector =
          connectorsByName[name as keyof typeof connectorsByName];
        return (
          <div
            className=" bg-white rounded-lg p-4 hover:cursor-pointer min-w-[25vw]"
            key={name}
            onClick={() => {
              setConnector(currentConnector);
            }}
          ></div>
        );
      })}
    </>
  );
};

export default TestComponent;

Upvotes: 0

Views: 159

Answers (1)

Lin Du
Lin Du

Reputation: 102347

You have to use type assertion for the return value of Object.keys() API. See Why doesn't Object.keys return a keyof type in TypeScript?

enum ConnectorNames {
    Injected = 'MetaMask',
    WalletConnect = 'WalletConnect',
    WalletLink = 'Coinbase Wallet',
    Magic = 'Email',
}

const connectorsByName: Record<ConnectorNames, any> = {
    [ConnectorNames.Injected]: () => 1,
    [ConnectorNames.WalletConnect]: () => '2',
    [ConnectorNames.WalletLink]: () => true,
    [ConnectorNames.Magic]: () => null,
};

(Object.keys(connectorsByName) as ConnectorNames[]).map((name) => {
    const currentConnector = connectorsByName[name];
})

TypeScript Playground

Upvotes: 2

Related Questions