gpt4 book ai didi

reactjs - React 和 Typescript 功能组件可以是 3 个接口(interface)之一

转载 作者:行者123 更新时间:2023-12-03 14:30:17 27 4
gpt4 key购买 nike

我正在尝试创建一个可以使用 3 个接口(interface)中的 1 个的组件,该组件能够根据传递给它的 props 来确定哪个接口(interface)。

interface CommonProps {
label: string;
icon?: React.ComponentType;
role?: string;
}

interface ButtonProps extends CommonProps {
handleOnClick: () => void;
selected?: boolean;
largeVariant?: boolean;
}

interface LinkProps {
to: string;
openInNewTab?: boolean;
}

interface HrefProps {
href: string;
openInNewTab?: boolean;
}

const Button: React.FC<ButtonProps | LinkProps | HrefProps> = props => {
const { label, handleOnClick, to, href, icon, openInNewTab } = props;
if (to || href) {
const Component = to ? Link : 'a';
return (
<StyledButton
component={Component}
target={openInNewTab ? '_blank' : undefined}
onMouseDown={(e: any) => {
href && pushMatomoExternalLink(e, href);
}}
{...props}
>
{icon && <StyledIcon icon={icon} />}
{label}
</StyledButton>
);
}
return (
<StyledButton onClick={handleOnClick} {...props}>
{icon && <StyledIcon icon={icon} />}
{label}
</StyledButton>
);
};

期望的行为,包括我期望看到的错误。

<Button label="View Report" handleOnClick={action('BUTTON CLICKED')} />

会推断该接口(interface)是 ButtonProps

<Button label="View Report" selected />

TypeScript error: Property 'handleOnClick' is missing in type '{ label: string; selected: boolean;}' but required in type 'ButtonProps'.

<Button label="View Report" openInNewTab />

会推断该接口(interface)将是 LinkProps 或 HrefProps

Property 'to' is missing in type '{ label: string; openInNewTab: boolean; }' but required in type 'LinkProps'.

Property 'href' is missing in type '{ label: string; openInNewTab: boolean; }' but required in type 'HrefProps'.

<Button label="View Report" href="/" openInNewTab />

会推断接口(interface)是 HrefProps

最佳答案

一种可能的解决方案是使用 type guards检查传递的 props 类型。类型保护应该有一个逻辑来找出它所传递的 props 的类型。在下面的代码中 propsIsButtonPropspropsIsLinkPropspropsIsHrefProps 是类型保护。

我简化了您的代码以展示主要思想。

function propsIsButtonProps (props: any): props is ButtonProps {
return props.selected !== undefined;
}
function propsIsLinkProps (props: any): props is LinkProps {
return props.to !== undefined;
}
function propsIsHrefProps (props: any): props is HrefProps {
return props.href !== undefined;
}

export const Button: React.FC<ButtonProps | LinkProps | HrefProps> = props => {
if (propsIsLinkProps(props) || propsIsHrefProps(props)) {
const Component = propsIsLinkProps(props) ? 'div' : 'a';
return (
<Component
target={props.openInNewTab ? '_blank' : undefined}
onMouseDown={(e: any) => {
propsIsHrefProps(props) && pushMatomoExternalLink(e, props.href);
}}
{...props}
>
{props.label}
</Component>
);
}
return (
<button onClick={props.handleOnClick} {...props}>
{props.label}
</button>
);
};

工作演示是 here

关于reactjs - React 和 Typescript 功能组件可以是 3 个接口(interface)之一,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/59709099/

27 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com