试图构建一个组件,该组件将返回一个或一个基于"as“的道具。我还想把道具从任何标记呈现出来,以提供灵活性。
Problem --我似乎无法使类型正确,这样返回的元素就不会给出错误。下面是我的示例(简化):
interface ButtonProps extends React.ButtonHTMLAttributes<HTMLButtonElement> {
as: "button";
}
interface AnchorProps extends React.AnchorHTMLAttributes<HTMLAnchorElement> {
as: "link";
}
const Button = ({
children,
as,
...restProps
}: AnchorProps | ButtonProps) => {
if (as === "link") return <a {...restProps}>{children}</a>;
if (as === "button") return <button {...restProps}>{children}</button>;
};如果我移除联合类型并使用AnchorProps或ButtonProps,然后注释掉各自的if/return语句,它就可以正常工作。但是,一旦我将它与AnchorProps | ButtonProps结合起来,它就会给我HTML和标签上的错误,说类型不匹配。
我觉得我离得很近,但到不了那里。
发布于 2022-09-28 19:21:58
如果你把道具拆开,然后缩小一个道具,就很难知道道具是相连的。
相反,缩小props对象本身,然后将其拆分。
const Button = (props: (AnchorProps | ButtonProps)) => {
if (props.as === "link") {
const { as, ...restProps } = props
return <a {...restProps}/>;
}
if (props.as === "button") {
const { as, ...restProps } = props
return <button {...restProps}/>;
}
return null
};children也可以与...restProps一起传播。你不需要特殊情况来处理这件事,除非你出于某种原因想要拦截它。
发布于 2022-09-28 19:26:12
这将是最好的办法。您将在组件中获得最好的类型支持,因为它将根据您提供的...rest支持来确定什么是as支持。
import React, { ReactNode } from 'react';
type AnchorProps = React.AnchorHTMLAttributes<HTMLAnchorElement>;
type ButtonProps = React.ButtonHTMLAttributes<HTMLButtonElement>;
enum ButtonComponentType {
LINK = 'link',
BUTTON = 'button',
}
type ButtonComponentProps<T extends ButtonComponentType> = {
as: T;
children: ReactNode;
// based on the "as" value, either intersect with ButtonProps or AnchorProps
} & (T extends ButtonComponentType.BUTTON ? ButtonProps : AnchorProps);
export function Button<T extends ButtonComponentType>({ children, as, ...restProps }: ButtonComponentProps<T>) {
if (as === ButtonComponentType.LINK) return <a {...(restProps as AnchorProps)}>{children}</a>;
if (as === ButtonComponentType.BUTTON) return <button {...(restProps as ButtonProps)}>{children}</button>;
return null;
}
// neither of these throw an error
function Test1() {
return (
// doesn't have "href" because the "as" prop is set to "button"
<Button as={ButtonComponentType.BUTTON} type="submit">
<p>test</p>
</Button>
);
}
function Test2() {
return (
// doesn't have button props
<Button as={ButtonComponentType.LINK} href="http://google.com">
<p>test</p>
</Button>
);
}https://stackoverflow.com/questions/73886686
复制相似问题