SvelteKit中use:clickOutside指令的TypeScript类型错误解决方法
解决Svelte自定义动作的TypeScript类型错误
问题场景
我编写了如下自定义动作函数:
export function clickOutside(node: HTMLElement) { const handleClick = (event: MouseEvent) => { if (!node.contains(event.target as Node)) { node.dispatchEvent(new CustomEvent('outclick')); } }; document.addEventListener('click', handleClick, true); return { destroy() { document.removeEventListener('click', handleClick, true); } }; }
并在组件中这样使用:
<div class="modal" use:clickOutside on:outclick={() => {showModal = false}}> {#if showModal} <SignIn /> {/if} </div>
此时出现TypeScript错误:Argument of type '{ class: string; "on:outclick": () => void; }' is not assignable to parameter of type 'Omit<Omit<HTMLAttributes,但代码实际运行正常,需要解决这个类型错误。
解决方法
方法1:扩展全局HTML属性类型
在项目的类型定义文件(如src/app.d.ts)中添加以下声明,扩展Svelte的HTML属性接口,让TypeScript识别on:outclick为合法事件:
declare namespace svelteHTML { interface HTMLAttributes<T> { 'on:outclick'?: () => void; } }
这种方式一劳永逸,所有使用该事件的地方都不会再报错。
方法2:局部类型断言
如果不想修改全局类型,可以给使用事件的元素添加类型断言,临时绕过类型检查:
<div class="modal" use:clickOutside on:outclick={() => {showModal = false}} as HTMLElement & {'on:outclick': () => void} > {#if showModal} <SignIn /> {/if} </div>
适合只在单个组件使用该事件的场景。
方法3:给自定义动作添加类型声明(推荐)
利用Svelte提供的Action泛型,给clickOutside动作明确声明它会触发的事件类型,让TypeScript自动推断:
import type { Action } from 'svelte'; export const clickOutside: Action<HTMLElement, undefined, { 'on:outclick': () => void }> = (node) => { const handleClick = (event: MouseEvent) => { if (!node.contains(event.target as Node)) { node.dispatchEvent(new CustomEvent('outclick')); } }; document.addEventListener('click', handleClick, true); return { destroy() { document.removeEventListener('click', handleClick, true); } }; };
这种方式既不需要修改全局类型,也无需每次使用都加断言,是最规范的解决方案。
内容的提问来源于stack exchange,提问作者jeff
相关产品推荐
相关产品推荐

