1

I'm trying to define this object type.

colors: {
  text: "#343D48", // body color and primary color
  text_secondary: "#02073E", // secondary body color
  heading: "#565F67", // primary heading color
  heading_secondary: "#0F2137", // heading color
  background: "#FFFFFF", // body background color
  background_secondary: "#F9FBFD", // secondary background color
  border_color: "#E5ECF4", // border color
  primary: "#78F0AC", // primary button and link color
  secondary: "#29CC5F", // secondary color - can be used for hover states
  muted: "#7B8188", // muted color
  dark: "#343D48",
  accent: "#609", // a contrast color for emphasizing UI
  yellow: "#F6C416",
  error: "#F65241",

  // highlight  a background color for highlighting text
  modes: {
    dark: {
      text: "#fff",
      background: "#000",
      primary: "#0cf",
      secondary: "#09c",
      muted: "#111",
    },
  },
},

This is what I wrote so far, I'm not sure how to define nested objects with TypeScript. How do I define the type for the code above? This is what I have so far:

export type Color = {
[colorName: string]: string;
};
5
  • do you really need to define a type for the above? or rather do you need to defined these colors in TypeScript? Commented May 30, 2022 at 0:54
  • your typing is technicallly correct, though we then need a way to prevent modes from being recursively available. Commented May 30, 2022 at 0:55
  • 1
    You just... nest nest it. tsplay.dev/w8ojPW But this isn't going to work well with a [colorName: string] index signature because modes is not a color name, and will not have a string as its value. Are you sure you want that index signature rather than every property being explicitly typed? PLease describe your actual goal a bit here so we can give you better advice. Commented May 30, 2022 at 0:58
  • @Alex Wayne I was trying not to do it all one by one but I guess I have too. Commented May 30, 2022 at 1:02
  • 1
    You could leave it untyped and use typeof colors to get the type of that object if you need it: type Colors = typeof colors but again, the right approach depends on what you want to do with this type. Commented May 30, 2022 at 1:04

1 Answer 1

2

In your current type definition, you have the following:

export type Color = {
    [colorName: string]: string;
};

The above code is the same as saying:

export type Color = Record<string, string>

Instead, you should clearly define each field in the type definition. Defining a Record specifies the key-type and value-type for the object but does not specify the name of each key or the type of each value (in case some keys have another data type).

In this case, you are looking for an interface:

export interface ColorDefinition {
  text: string;
  text_secondary: string;
  heading: string;
  heading_secondary: string;
  background: string;
  background_secondary: string;
  border_color: string;
  primary: string;
  secondary: string;
  muted: string;
  dark: string;
  accent: string;
  yellow: string;
  error: string;
  modes: {
    dark: {
      text: string;
      background: string;
      primary: string;
      secondary: string;
      muted: string;
    };
  };
}

export type { ColorDefinition };

The same way you can also use type to define an interface:

type ColorDefinition = {
    primary: string;
    ...
}

export type { ColorDefinition };

If you would like to write this interface (since you have repeating key-value pairs) correctly, I would write your type definition as such:

interface SimpleColorDefinition {
    text: string;
    background: string;
    primary: string;
    secondary: string;
    muted: string;
}

interface UIColorDefinition extends SimpleColorDefinition {
    text_secondary: string;
    heading: string;
    heading_secondary: string;
    background_secondary: string;
    border_color: string;
    dark: string;
    accent: string;
    yellow: string;
    error: string;
    modes: {
        dark: SimpleColorDefinition;
    };
}

If you want the modes key to be an object with any value for key names, then you can do this instead:

modes: Record<string, SimpleColorDefinition>
Sign up to request clarification or add additional context in comments.

Comments

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.