简体   繁体   中英

Typescript access object key dynamically

I have Theme.ts file like below

export default {
  COLORS: {
    DEFAULT: '#172B4D',
    PRIMARY: '#5E72E4',
    SECONDARY: '#F7FAFC',
  }
};

In my button component I import above theme file like this --> import argonTheme from "../constants/Theme";

In my button component I want to get access to that color dynamically like this

 const { small, shadowless, children, color, style, fontSize } = props;
 const colorStyle = color && argonTheme.COLORS[color.toUpperCase()];

This line gives me typescript error --> const colorStyle = color && argonTheme.COLORS[color.toUpperCase()];

This is the error I'm getting

Element implicitly has an 'any' type because expression of type 'any' can't be used to index type '{ DEFAULT: string; PRIMARY: string; SECONDARY: string ...

How can I write this line in typescript?

const colorStyle = color && argonTheme.COLORS[color.toUpperCase()];

You have to provide a type for the COLORS object:

// Theme.ts
const COLORS: Record<string, string> =  {
  DEFAULT: '#172B4D',
  PRIMARY: '#5E72E4',
  SECONDARY: '#F7FAFC',
}

export default { COLORS };

// Other Component:
const color= 'PRIMARY';
const colorStyle = color && COLORS[color.toUpperCase()];

A working example here .

I believe the best option is to have an enum matching the properties of that object you have, declaring keys as string is a loose solution that might allow you have a key that does not exist.

enum ColorOptions {
  DEFAULT = 'DEFAULT',
  PRIMARY = 'PRIMARY',
  SECONDARY = 'SECONDARY',
}

Than you can safely do it like

const colorStyle = color && COLORS[ColorOptions.SECONDARY];

full code:

const COLORS = {
  DEFAULT: '#172B4D',
  PRIMARY: '#5E72E4',
  SECONDARY: '#F7FAFC',
}

enum ColorOptions {
  DEFAULT = 'DEFAULT',
  PRIMARY = 'PRIMARY',
  SECONDARY = 'SECONDARY',
}
const color = ColorOptions.PRIMARY;
const colorStyle = color && COLORS[color];
console.log(colorStyle);

or even consider killing the COLOR object and have just an enum

export enum COLORS {
  DEFAULT = '#172B4D',
  PRIMARY = '#5E72E4',
  SECONDARY = '#F7FAFC',
}
console.log(colorStyle); // #5E72E4

or if your code is already validating color input and you just want to touch that line and shut TS you could:

const colorStyle = color && argonTheme.COLORS[color.toUpperCase() as keyof typeof COLORS]; 

Set a type for you for your COLORS, otherwise the any type would be set by default:

in your case its stringkey with string value, thus should look like

export default {
    const COLORS :{ [key: string]: string } =  {
      DEFAULT: '#172B4D',
      PRIMARY: '#5E72E4',
      SECONDARY: '#F7FAFC',
    }
};

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM