Evento de acción personalizada tipo Svelte (svelte-kit) con TypeScript
Estoy usando la acción clickOutside abajo.
export function clickOutside(node: HTMLElement) {
function detect({ target }: MouseEvent) {
if (!node.contains(target as Node)) {
node.dispatchEvent(new CustomEvent('clickoutside'));
}
}
document.addEventListener('click', detect, { passive: true, capture: true });
return {
destroy() {
document.removeEventListener('click', detect);
},
};
Este es el error que todavía obtengo, cuando paso el cursor sobre on:clickoutside={() => {}}
Type '{ onclickoutside: () => void; class: string; }' is not assignable to type 'HTMLProps<HTMLDivElement>'.
Property 'onclickoutside' does not exist on type 'HTMLProps<HTMLDivElement>'}
Probé esto en svelte kit app.d.ts
declare namespace svelte.JSX {
interface HTMLAttributes<T> {
clickoutside?: (event: CustomEvent) => void;
}
}
También probé HTMLProps<T> y HTMLProps<HTMLDivElement> y muchas otras variaciones y nada funciona. Reinicié el servidor de ts 25 veces, así que no es eso. Este es el enlace para la documentación
Y no, esto no es un duplicado porque literalmente revisé todas las otras respuestas y no funcionan. como esta: ejemplo
Respuesta #1
De hecho, acabo de tener el mismo problema, y los documentos ofrecen una gran solución. Lo que hice fue modificar mi app.d.ts para incluir mi interfaz. Aquí está mi acción:
import { browser } from '$app/environment'
let iob: IntersectionObserver
const initializeIob = () => {
console.log('called')
iob = new IntersectionObserver((entries) => {
entries.forEach((entry) => {
const customEventName = entry.isIntersecting
? 'viewportEnter'
: 'viewportExit'
entry.target.dispatchEvent(new CustomEvent(customEventName))
})
})
}
const viewport = (element: HTMLElement) => {
if (!iob && browser) initializeIob()
iob.observe(element)
return {
destroy() {
iob.unobserve(element)
},
}
}
export default viewport
Puedes ver que tengo viewportEnter que debe usarse con on: en mi elemento HTML. El archivo àpp.d.ts modificado se ve así:
declare global {
namespace App {
// interface Error {}
// interface Locals {}
// interface PageData {}
// interface Platform {}
}
namespace svelteHTML {
interface HTMLAttributes<T> {
'on:viewportEnter'?: (event: CustomEvent) => void
'on:viewportExit'?: (event: CustomEvent) => void
}
}
}
export {}
usándolo en mi elemento html
<h1
style="text-align: center;"
use:viewport
on:viewportEnter={() => {
console.log("Entered");
}}
on:viewportExit={() => {
console.log("Exit");
}}
>
Hello Actions with Intersection observer!
</h1>
y funciona como se espera.
Respuesta #2
La declaración correcta actual debería ser:
declare namespace svelteHTML {
interface HTMLAttributes<T> {
'on:clickoutside'?: (event: CustomEvent) => void;
}
}
(Las versiones anteriores usaban un espacio de nombres/tipos diferente, consulte la guía de migración.)
