我正在尝试创建一个 Svelte 5 组件,该组件根据 href prop 的存在来呈现按钮或锚元素,但是我遇到了 TS 错误。Button.svelte
我正在尝试创建一个 Svelte 5 组件,该组件根据 href prop 的存在来呈现按钮或锚元素,但是我遇到了 TS 错误。
按钮.svelte
<script lang="ts">
import type { HTMLButtonAttributes, HTMLAnchorAttributes } from 'svelte/elements';
type Props = HTMLAnchorAttributes | HTMLButtonAttributes;
const {
href,
children,
...restProps
}: Props = $props();
</script>
{#if href}
<a {href} {...restProps}>
{@render children()}
</a>
{:else}
<button {...restProps}>
{@render children()}
</button>
{/if}
上述代码会产生两个错误:
href
Props 类型上不存在。
restProps
:类型为 ... 的参数不能分配给类型为 'HTMLProps<\'a\', HTMLAtributes>' 的参数
我认为检查是否存在 href
将充当类型保护,允许我将正确的道具传播到正确的元素上。
任何见解都值得赞赏。提前致谢。
通过解构拆分属性, href
与其他 props 之间的关系就丢失了。 href
然后检查除了自身之外对其他任何东西都没有影响 href
。
如果不拆分属性并通过 检查 in
,则锚点情况可以工作,但按钮会出现问题,因为锚点和按钮都具有具有 type
不同可能值的属性,并且缺少 href
属性在逻辑上 并不 意味着用户只指定了按钮属性,因为 href
锚点中不需要存在属性。
可以通过更严格的类型来强制执行 Props
:
<script lang="ts">
import type { HTMLButtonAttributes, HTMLAnchorAttributes } from 'svelte/elements';
type Props =
({ href: string } & HTMLAnchorAttributes) |
HTMLButtonAttributes;
const { children, ...props }: Props = $props();
</script>
{#if 'href' in props}
<a {...props}>
{@render children?.()}
</a>
{:else}
<button {...props}>
{@render children?.()}
</button>
{/if}