Svelte TypeScript中的自定义事件

28

我在我的Svelte-TypeScript项目中使用clickOutside指令,当我给相关元素分配自定义事件时,出现了以下错误

Type '{ class: string; onclick_outside: () => boolean; }' is not assignable to type 'HTMLProps<HTMLDivElement>'.
  Property 'onclick_outside' does not exist on type 'HTMLProps<HTMLDivElement>'

这是我的代码片段:

{#if profileToolbar}
<div
    transition:fly={{ y: -20, duration: 300 }}
    use:clickOutside={profileToolbarContainer}
    on:click_outside={() => (profileToolbar = !profileToolbar)}
    class="origin-top-right absolute right-0 mt-2 w-48 rounded-md
    shadow-lg z-10 shadow-md">

这是我目前正在使用的clickOutside指令https://svelte.dev/repl/0ace7a508bd843b798ae599940a91783?version=3.16.7

我是typescript的新手,不知道该从哪里开始我的谷歌搜索,有人知道如何解决这个问题吗?谢谢你的帮助

5个回答

35

根据文档,您可以在项目中的任何位置创建一个.d.ts文件,并将以下内容放入该文件中:

declare namespace svelte.JSX {
  interface HTMLAttributes<T> {
    onclick_outside: () => void
  }
}

请阅读文档以获取更多详细信息。


1
完美运行!我只需要将它更改为“interface HTMLProps”,感谢你的帮助和建议,我知道Svelte TypeScript仍然很新,但不幸的是,目前不是我做决定的人,但我会记住你的话。 - KawishBit
给hackape:我知道这有点跑题,但你能分享一下在使用Svelte和TS时遇到的其他不便吗?我是该领域的维护者之一,像这样的反馈非常有价值(因为它很少见)。 - dummdidumm
@dummdidumm 我知道把这两个东西联系起来并不容易,所以对你的工作表示赞赏!但很抱歉我没有太多可以分享的,因为那是半年前的事情了,我不记得具体的细节。我只能记得整个经验的总体印象是可以接受,但并不完全令人满意。最后我想,还是尽可能将 TS 的内容保留在 .ts 文件中,并将其导入到 .svelte 文件中以减少混杂和忽略警告。后来我又回到了 React 的舒适世界。 - hackape
我曾试图将Svelte REPL移植到VSCode扩展中,但被打断后只完成了一半。我可以找时间重新捡起来并刷新我的记忆。如果我有任何值得分享的东西,我会再联系你的。 - hackape
感谢您的快速回复!半年后情况应该会更好,但我同意仍然存在一些问题。关于您的REPL:如果您只想要REPL的“显示编译输出”行为,现在可以通过Svelte for VS Code扩展实现。命令是“Svelte: Show Compiled Code”。 - dummdidumm
1
好的,我也想要预览功能。你是 vscode 扩展的维护者吗? - hackape

16

这个声明对我起了作用

declare namespace svelte.JSX {
  interface DOMAttributes<T> {
    onclick_outside?: CompositionEventHandler<T>;
  }
}
不要忘记在tsconfig.json中指定自定义类型声明的位置。

你把它放在哪里? - Marcus
1
@Marcus和未来的读者们:SvelteKit在src文件夹内附带了一个app.d.ts。这是一个很好的位置,即使您正在使用“普通”的Svelte也是如此。相比之下,Angular曾经为相同的目的在其src文件夹中生成一个typings.d.ts - J.P.

15

好的,那么现有的答案对我只有部分有效。考虑到 clickOutside 行为会触发一个名为 click_outside 的自定义事件,我得出以下解决方案:

declare namespace svelte.JSX {
    interface HTMLProps<T> {
        onclick_outside?: (e: CustomEvent) => void;
    }
}

1
那是唯一一个实际起作用的,应该标记为答案。 - poliskalien

8

更新 7/23/23

新的 SvelteKit 需要这个:

这是我的 src/app.d.ts 文件。

// See https://kit.svelte.dev/docs/types#app
// for information about these interfaces
declare global {
    namespace App {
        // interface Error {}
        // interface Locals {}
        // interface PageData {}
        // interface Platform {}
    }

    declare namespace svelteHTML {
        interface HTMLAttributes<T> {
            'on:clickOutside'?: CompositionEventHandler<T>;
        }
    }
}

export { };

J


对于那些阅读这个答案的人:在这种新格式中的一个要注意的地方是属性名称中包含了冒号 :。所以应该使用 on:clickOutside 而不是 onclickOutside - Coo
我的自定义事件和类被称为clickOutside,所以对我来说很有效。 - Jonathan

6
对我来说,以下方法有效:
declare namespace svelteHTML {
    interface HTMLAttributes<T> {
        "on:click_outside"?: CompositionEventHandler<T>;
    }
}

在您的 src/app.d.ts 内部。

基于 这个


网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接