Home > Software design >  TypeScript type that is a list of possible strings which are keys of an object
TypeScript type that is a list of possible strings which are keys of an object

Time:11-13

I have an object that looks something like this

palette: {
    black: "#000",
    white: "#fff",
    primary: {
      "50": "#somecolor",
      "100": "#somecolor",
      "300": "#somecolor",
      "500": "#somecolor",
      "700": "#somecolor",
    },
    grey: {
      "50": "#somecolor",
      "300": "#somecolor",
      "500": "#somecolor",
      "700": "#somecolor",
      "900": "#somecolor",
    },
    green: {
      "100": "#somecolor",
      "300": "#somecolor",
      "500": "#somecolor",
      "700": "#somecolor",
    },
    blue: {
      "100": "#somecolor",
      "300": "#somecolor",
      "500": "#somecolor",
      "700": "#somecolor",
    },
    pink: {
      "100": "#somecolor",
      "300": "#somecolor",
      "500": "#somecolor",
      "700": "#somecolor",
    },
    red: {
      "300": "#somecolor",
      "500": "#somecolor",
      "700": "#somecolor",
    },
    background: {
      "500": "#somecolor",
      "700": "#somecolor",
    }
}

I want to create a TypeScript type that is only a subset of some of the keys. My ideal type would look like const theme = ["blue", "green", "pink", "primary"] as const or type Theme = "blue" | "green" | "primary" | "pink"

I am unable to extract this type. The purpose of this type is to do things like: const currentColor = palette[theme][500] where theme is a variable that can be either the Theme or theme type from the above paragraph.

Not sure if it matters but I am in a NextJS React Native environment.

How can I do this?

CodePudding user response:

you should use index of array like this: palette[theme[2]][500]

export default function Home() {
  type themeItemType = "blue" | "green" | "primary" | "pink";
  const theme: themeItemType[] = ["blue", "green", "pink", "primary"];
  console.log(palette[theme[2]][500]) //#somecolor

  return <div>{palette[theme[2]][500]}</div>;
}

const palette = {
  black: "#000",
  white: "#fff",
  primary: {
    "50": "#somecolor",
    "100": "#somecolor",
    "300": "#somecolor",
    "500": "#somecolor",
    "700": "#somecolor",
  },
  grey: {
    "50": "#somecolor",
    "300": "#somecolor",
    "500": "#somecolor",
    "700": "#somecolor",
    "900": "#somecolor",
  },
  green: {
    "100": "#somecolor",
    "300": "#somecolor",
    "500": "#somecolor",
    "700": "#somecolor",
  },
  blue: {
    "100": "#somecolor",
    "300": "#somecolor",
    "500": "#somecolor",
    "700": "#somecolor",
  },
  pink: {
    "100": "#somecolor",
    "300": "#somecolor",
    "500": "#somecolor",
    "700": "#somecolor",
  },
  red: {
    "300": "#somecolor",
    "500": "#somecolor",
    "700": "#somecolor",
  },
  background: {
    "500": "#somecolor",
    "700": "#somecolor",
  },
}; 

CodePudding user response:

If I understand correctly, you want to to build a partial union out of the object keys. if that is the case, this should do the work

type PaletteKeys = keyof Partial<Record<keyof typeof palette, string>>

it will allow you to build the following unions:

type Union1 = 'blue' | 'green' | 'primary' | 'pink';
type Union2 = 'blue' | 'primary';
// and any other "Partial" union of the "palette" keys
  • Related