Home > Mobile >  Type of nested object with variable keys from a list
Type of nested object with variable keys from a list

Time:01-09

I have the following two objects that define variable styles for a Button.

interface colorProps {
  cyan: string;
  white: string;
  gray: string;
}

interface variantProps {
  solid: string;
  outline: string;
}

type styleProps = {  // unused
  [Key in keyof variantProps]: {[key in keyof colorProps]: string} | colorProps | string | keyof colorProps;
}

interface CustomProps {
  [key: string]: string | {[key: string]: string} | keyof colorProps | colorProps | variantProps | keyof variantProps;
}

const baseStyles: CustomProps = {
  solid: 'xxx',
  outline: 'xxx',
}

const variantStyles: CustomProps = {
  solid: {
    cyan: 'xxx',
    white: 'xxx',
    gray: 'xxx',
  },
  outline: {
    gray: 'xxx',
  },
}

I have defined the type of the input props for the button as such:

interface ButtonProps {
    href?: string;
    variant?: keyof variantProps;//'solid' | 'outline';
    color?: keyof colorProps;//'cyan' | 'white' | 'gray';
    className?: string;
}

I am trying to do something that I can easily do in other typed languages, namely just:

variantStyles[variant][color]

So I am trying to get the correct style based on the values of variant and color. As you can see I have tried a bunch of stuff inside CustomProps (apart from just typing any) but still I get:

Element implicitly has an 'any' type because expression of type 'keyof colorProps' can't be used to index type 'string | colorProps | { [key: string]: string; } | variantProps'.
  Property 'cyan' does not exist on type 'string | colorProps | { [key: string]: string; } | variantProps'.ts(7053)

CodePudding user response:

You are trying to access properties of an object using keys that are of the type keyof variantProps or keyof colorProps. The type of the object itself is CustomProps, which is a more general type that allows for any string keys..

You can update the type of variantStyles to better reflect the structure of the object. You can define a new type that maps the keys of variantProps to objects with keys of type keyof colorProps.

Here's a lil example:

type VariantStyles = {
  [Key in keyof variantProps]: { [key in keyof colorProps]: string };
}

const variantStyles: VariantStyles = {
  solid: {
    cyan: 'xxx',
    white: 'xxx',
    gray: 'xxx',
  },
  outline: {
    gray: 'xxx',
  },
}

CodePudding user response:

Change the CustomProps interface to:

interface CustomProps {
    [key: string]: {
        [key: string]: string | keyof colorProps | colorProps | variantProps | keyof variantProps;
    };
}
  • Related