type ButtonVariant = 'action' | 'hero';
type Size = 'small' | 'medium' | 'large';
export interface ButtonProps {
variant: ButtonVariant;
size?: Size;
}
export default function Button(props: ButtonProps): ReactElement {
const { variant } = props;
if (variant === 'hero')) {
return <HeroButton {...props} />;
}
if (variant === 'pill') {
return <PillButton {...props} />;
}
}
在上面的代码中,我有两个React按钮的变体:HeroButton
和PillButton
。
两个按钮都将“ ButtonProps”作为其道具类型。但是,我想让HeroButton仅 期望大小为“中”或“大”。 PillButton应接受“小”,“中”或“大”作为其大小尺寸。
问题:如何编写ButtonProps
接口,以使Button
组件允许(并在VS Code中建议)'small' | 'medium' | 'large'
作为大小道具变体道具为“药丸”,但仅当变体道具为“英雄”时才允许'medium' | 'large'
?
注意:我已经研究了TypeScript区分联合来解决此问题,但尚未设法使它正常工作。
答案 0 :(得分:1)
尝试一下:
export interface HeroButtonProps {
variant: 'hero';
size?: 'medium' | 'large';
}
export interface PillButtonProps {
variant: 'pill';
size?: 'small' | 'medium' | 'large';
}
export type ButtonProps = HeroButtonProps | PillButtonProps;
然后将HeroButton
更改为仅接受HeroButtonProps
,对于PillButton
同样如此。
答案 1 :(得分:1)
类似的东西应该起作用
type DiscUnion =
| { variant: "hero"; size?: "medium" | "large" }
| { variant: "pill"; size?: "small" | "medium" | "large" };
export default function Button(props: DiscUnion): any {
if (props.variant === "hero") {
const w = props.size; //typeof w is "medium" | "large"
}
if (props.variant === "pill") {
const w = props.size; //typeof w is "small" | "medium" | "large"
}
}
// allowed
Button({ variant: "hero", size: "medium" });
// not allowed
Button({ variant: "hero", size: "small" });
请注意,我们不会破坏变体,否则您将失去控制流分析https://github.com/microsoft/TypeScript/issues/9998