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;
};
}