如何正确键入此对象转换?
How can I correctly type this object converting?
如何实现此转换案例的类型安全?我正在映射 palette
并将任何带有条目的对象转换为键值对,就像 tailwindcss 对其颜色配置所做的那样。但是 colors
的类型不包含灰色,而只包含未转换的输入键作为类型。
const palette = {
white: 'white',
gray: {
100: '#eeeeee',
200: '#e0e0e0',
300: '#bbbbbb',
},
};
type ColorVariants = keyof typeof palette;
function convertToColors(color: ColorVariants) {
return Object.fromEntries(
Object.entries(palette[color]).map(([key, value]) => [`${color}${key}`, value]),
);
}
/**
result ->
{
"gray100": "#eeeeee",
"gray200": "#e0e0e0",
"gray300": "#bbbbbb",
}
*/
const grays = convertToColors("gray")
这里的类型不正确
// Resulting Type
// const colors: {
// white: string;
// }
//
// Expecting Type
// const colors: {
// white: string;
// gray100: string;
// gray200: string;
// gray300: string;
// }
const colors = {
white: palette.white,
...convertToColors("gray")
}
你可以在这种情况下使用 union :
type ColorVariants = string | {[prop:number]:string};
您现在可以 template literal types.
让我们将 convertToColors
编辑为:
function convertToColors<Color extends ColorVariants>(color: Color): Variants<Color, typeof palette[Color]> {
return Object.fromEntries(
Object.entries(palette[color]).map(([key, value]) => [`${color}${key}`, value]),
) as never; // cast to return type; "ignore" error
}
它接受一种颜色,并为我们提供该颜色的变体对象。
这是建议的Variants
类型:
type Variants<K extends string, T extends string | Record<string | number, string>> = T extends string ? T : {
[V in keyof T as V extends string | number ? `${K}${V}` : never]: T[V];
};
首先它会检查给定的颜色是否没有任何变体(它只是一个字符串,而不是一个对象)。
然后它将变体中的所有键重新映射为变体 + 它的强度。
你可以看到它运行得非常好here。
如何实现此转换案例的类型安全?我正在映射 palette
并将任何带有条目的对象转换为键值对,就像 tailwindcss 对其颜色配置所做的那样。但是 colors
的类型不包含灰色,而只包含未转换的输入键作为类型。
const palette = {
white: 'white',
gray: {
100: '#eeeeee',
200: '#e0e0e0',
300: '#bbbbbb',
},
};
type ColorVariants = keyof typeof palette;
function convertToColors(color: ColorVariants) {
return Object.fromEntries(
Object.entries(palette[color]).map(([key, value]) => [`${color}${key}`, value]),
);
}
/**
result ->
{
"gray100": "#eeeeee",
"gray200": "#e0e0e0",
"gray300": "#bbbbbb",
}
*/
const grays = convertToColors("gray")
这里的类型不正确
// Resulting Type
// const colors: {
// white: string;
// }
//
// Expecting Type
// const colors: {
// white: string;
// gray100: string;
// gray200: string;
// gray300: string;
// }
const colors = {
white: palette.white,
...convertToColors("gray")
}
你可以在这种情况下使用 union :
type ColorVariants = string | {[prop:number]:string};
您现在可以 template literal types.
让我们将 convertToColors
编辑为:
function convertToColors<Color extends ColorVariants>(color: Color): Variants<Color, typeof palette[Color]> {
return Object.fromEntries(
Object.entries(palette[color]).map(([key, value]) => [`${color}${key}`, value]),
) as never; // cast to return type; "ignore" error
}
它接受一种颜色,并为我们提供该颜色的变体对象。
这是建议的Variants
类型:
type Variants<K extends string, T extends string | Record<string | number, string>> = T extends string ? T : {
[V in keyof T as V extends string | number ? `${K}${V}` : never]: T[V];
};
首先它会检查给定的颜色是否没有任何变体(它只是一个字符串,而不是一个对象)。 然后它将变体中的所有键重新映射为变体 + 它的强度。
你可以看到它运行得非常好here。