0

I have a object with all of our design tokens like this:

const Tokens = {
  neutralColor: {
    dark: {
      '100': #123456,
      '200': #223456,
    },
    medium: {
      '100': #654321,
      '200': #876543,
    },
    light: {
      '100': #009988,
      '200': #334411,
    }
  },
  feedbackColor: {
    // similar like above
  },
  // other color family here
}

In my componente I need to limit the color props to only accept values in the tokens, like:

<Typography color={Tokens.neutralColor.dark["100"]}>label</Typography>

// or

<Typography color="#123456">label</Typography>
// since Tokens.neutralColor.dark["100"] = #123456

As I should, I should create a type like:

type Color = "#123456" | "#223456" | "#654321" | "and so on"

type TypographyProps = {
  color: Color
}

function Typography(props: TypographyProps) { ... }

Is there a way to create this Typescript type dynamically based on my token object?

2 Answers 2

1

Yes, it is possible :

  • declare your Tokens "as const", so that your color are interpeted as a literal type, not as string ;
  • get the deep value of your object.
const Tokens = {
  neutralColor: {
    dark: {
      '100': '#123456',
      '200': '#223456',
    },
    medium: {
      '100': '#654321',
      '200': '#876543',
    },
    light: {
      '100': '#009988',
      '200': '#334411',
    }
  }
} as const;

type DeepValueOf<T> = T extends string ? T : DeepValueOf<T[keyof T]>;
type AllowedColor = DeepValueOf<typeof Tokens>;

TS Playground

Sign up to request clarification or add additional context in comments.

1 Comment

Thank you so much! It just works for me! I got a little bit about typeof and keyof, reading about it now, thank you so much again!
1

You can easily get type of any part of your object.

Notice that:

  • I changed your Tokens object to a constant
  • You can get a type of any object with typeof obj
  • you can get keys of any type T with keyof T
const Tokens = {
  neutralColor: {
    dark: {
      '100': '#123456',
      '200': '#223456',
    },
    medium: {
      '100': '#654321',
      '200': '#876543',
    },
    light: {
      '100': '#009988',
      '200': '#334411',
    }
  },
  feedbackColor: {
    // similar like above
  },
  // other color family here
} as const;



type LeafTypes<T> = T extends string
  ? T
  : {
      [Property in keyof T]: LeafTypes<T[Property]>;
    }[keyof T];

type Color = LeafTypes<typeof Tokens>

Playground link

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.