Reputation: 5524
I'm trying to create object with generic property name
type ColorStyle<T extends string> = Record<ColorType, Record<T, string>>;
function getColorStyle<T extends string>(propertyName: T): ColorStyle<T> {
return {
accent: { [propertyName]: colors.accent },
primary: { [propertyName]: colors.primary },
secondary: { [propertyName]: colors.secondary },
tertiary: { [propertyName]: colors.tertiary },
black: { [propertyName]: colors.black },
white: { [propertyName]: colors.white },
gray: { [propertyName]: colors.gray },
gray2: { [propertyName]: colors.gray2 },
}
}
Error I'm getting is
Type '{ [x: string]: string; }' is not assignable to type 'Record<T, string>
I wanted to use it us such:
const colorStyle = getColorStyle('color');
const primaryColor = colorStyle.primary.color;
const backgroundColorStyle = getColorStyle('backgroundColor');
const primaryBackgroundColor = backgroundColorStyle.primary.backgroundColor;
EDIT:
export const colors = {
accent: "#F3534A",
primary: "#0AC4BA",
secondary: "#2BDA8E",
tertiary: "#FFE358",
black: "#323643",
white: "#FFFFFF",
gray: "#9DA3B4",
gray2: "#C5CCD6"
};
export type ColorType = keyof typeof colors;
Upvotes: 0
Views: 78
Reputation: 17474
I think the problem is from the way Typescript infers your body { [propertyName]: colors.accent }
to { [x: string]: string }
which is different from { [P in string]: string } (Record<string, string>)
. But it allows you to cast { [propertyName]: colors.accent } as Record<T, string>
which means you can just simply cast your result as your return value:
Cast single item:
return {
accent: { [propertyName]: colors.accent } as Record<T, string>,
// ...
}
Or you can cast entire object:
return {
accent: { [propertyName]: colors.accent },
// ...
} as ColorStyle<T>
Upvotes: 2