我认为您想要所有子对象的属性的并集.(如果我错了,请纠正我).
首先,通过追加as const
使主题对象保持不变:
const themes = {
...
} as const;
然后,您可以获得所有属性的交集(窄):
type CommonObjectNarrow = typeof themes["bordered"] | typeof themes["simple"] | typeof themes["dark"] | typeof themes["light"];
type CommonPropsNarrow = keyof CommonObjectNarrow;
// "background" | "radius" | "padding" | "mobilePadding" | "color"
或所有属性的并集(宽):
type ThemeKeys = keyof typeof themes;
type Props<K extends ThemeKeys> = (keyof typeof themes[K]);
type CommonPropsWide = Props<"bordered"> | Props<"simple"> | Props<"dark"> | Props<"light">;
// "background" | "borderWidth" | "radius" | "padding" | "mobilePadding" | "color"
// | "border" | "colorArrow" | "backgroundIcon" | "borderIcon" | "colorArrowIsOpen"
// | "backgroundIconIsOpen" | "borderIconIsOpen" | "storyColor"
type CommonObjectWide = {
[k in CommonPropsWide]: string;
}
以下是typescript playground人中可以证实这一点的东西:
declare const COLORS:{ [x:string]: string};
declare const BorderRadius: { componentRadius: string};
const themes = {
bordered: {
background: COLORS.BgMain,
borderWidth: '1px',
radius: '4px',
padding: '20px',
mobilePadding: '15px',
color: COLORS.TextPrimary
},
simple: {
background: 'transparent',
borderWidth: '1px 0',
radius: '0px',
padding: '20px 0',
mobilePadding: '15px 0',
color: COLORS.TextPrimary
},
light: {
border: COLORS.BgLight,
background: COLORS.BgLight,
color: COLORS.TextPrimary,
colorArrow: COLORS.GRAY_DARK,
backgroundIcon: COLORS.BgSecondary,
borderIcon: COLORS.BgSecondary,
colorArrowIsOpen: COLORS.GRAY_DARK,
backgroundIconIsOpen: COLORS.Outline_Light,
borderIconIsOpen: COLORS.Outline_Light,
radius: BorderRadius.componentRadius,
padding: '20px 24px',
mobilePadding: '15px',
storyColor: COLORS.BgMain,
},
dark: {
border: COLORS.Control,
background: COLORS.Control,
color: COLORS.TextWhite,
colorArrow: COLORS.Control,
backgroundIcon: COLORS.GRAY_DARK,
borderIcon: COLORS.GRAY_DARK,
colorArrowIsOpen: COLORS.Control,
backgroundIconIsOpen: COLORS.TextWhite,
borderIconIsOpen: COLORS.TextWhite,
radius: BorderRadius.componentRadius,
padding: '20px 24px',
mobilePadding: '15px',
storyColor: '#3D3D3D',
},
};
type CommonObjectNarrow = typeof themes["bordered"] | typeof themes["simple"] | typeof themes["dark"] | typeof themes["light"];
type CommonPropsNarrow = keyof CommonObjectNarrow; // "background" | "radius" | "padding" | "mobilePadding" | "color"
type ThemeKeys = keyof typeof themes;
type Props<K extends ThemeKeys> = (keyof typeof themes[K]);
type CommonPropsWide = Props<"bordered"> | Props<"simple"> | Props<"dark"> | Props<"light">;
// "background" | "borderWidth" | "radius" | "padding" | "mobilePadding" | "color"
// | "border" | "colorArrow" | "backgroundIcon" | "borderIcon" | "colorArrowIsOpen"
// | "backgroundIconIsOpen" | "borderIconIsOpen" | "storyColor"
type CommonObjectWide = {
[k in CommonPropsWide]: string;
}
更新
在回应OP的 comments 时:
declare enum COLORS {
TextPrimary = "#1",
BgMain = "#1",
BgLight = "#2",
GRAY_DARK = "#3",
BgSecondary = "#4",
Outline_Light = "#5",
Control = "#6",
TextWhite = "#7"
};
declare const BorderRadius: { componentRadius: "5pix 0"};
const themes = {
bordered: {
background: COLORS.BgMain,
borderWidth: '1px',
radius: '4px',
padding: '20px',
mobilePadding: '15px',
color: COLORS.TextPrimary
},
simple: {
background: 'transparent',
borderWidth: '1px 0',
radius: '0px',
padding: '20px 0',
mobilePadding: '15px 0',
color: COLORS.TextPrimary
},
light: {
border: COLORS.BgLight,
background: COLORS.BgLight,
color: COLORS.TextPrimary,
colorArrow: COLORS.GRAY_DARK,
backgroundIcon: COLORS.BgSecondary,
borderIcon: COLORS.BgSecondary,
colorArrowIsOpen: COLORS.GRAY_DARK,
backgroundIconIsOpen: COLORS.Outline_Light,
borderIconIsOpen: COLORS.Outline_Light,
radius: BorderRadius.componentRadius,
padding: '20px 24px',
mobilePadding: '15px',
storyColor: COLORS.BgMain,
},
dark: {
border: COLORS.Control,
background: COLORS.Control,
color: COLORS.TextWhite,
colorArrow: COLORS.Control,
backgroundIcon: COLORS.GRAY_DARK,
borderIcon: COLORS.GRAY_DARK,
colorArrowIsOpen: COLORS.Control,
backgroundIconIsOpen: COLORS.TextWhite,
borderIconIsOpen: COLORS.TextWhite,
radius: BorderRadius.componentRadius,
padding: '20px 24px',
mobilePadding: '15px',
storyColor: '#3D3D3D',
},
};
type ThemeKeys = keyof typeof themes;
type Theme<K extends ThemeKeys> = typeof themes[K];
type Props<K extends ThemeKeys> = (keyof typeof themes[K]);
type CommonPropsWide = Props<"bordered"> | Props<"simple"> | Props<"dark"> | Props<"light">;
type KeyTypes1<k extends string, themeKeys extends ThemeKeys[] = ["bordered","simple","dark","light"], t extends any = never> =
themeKeys extends [infer HEAD, ... infer TAIL] ?
TAIL extends ThemeKeys[] ?
HEAD extends ThemeKeys ?
(k extends keyof Theme<HEAD> ? KeyTypes1<k,TAIL,Theme<HEAD>[k] | t> : KeyTypes1<k,TAIL,t>)
: never : never : t;
type CommonObjectWide = Partial<{
[k in CommonPropsWide]: KeyTypes1<k>
}>
const obj1: CommonObjectWide = {
color: COLORS.BgSecondary,
background: "", //COLORS.BgMain
radius: BorderRadius.componentRadius, // ""
}
const obj2: CommonObjectWide = {
color: "", // COLORS.BgSecondary, error, must be color
background: COLORS.BgMain,
radius: "5pix 0"
}
显示为TypeScript PLayground.