You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

如何为Svelte自定义Action的自定义事件添加类型(use指令场景)

为Svelte自定义Action添加自定义事件类型

1. 导入核心类型

先从svelte/action里导入ActionReturn类型,这是定义带返回值的自定义Action的核心类型,同时按需导入zod相关类型:

import type { ActionReturn } from 'svelte/action';
import type { ZodSchema } from 'zod';

2. 声明自定义事件类型

和组件里用$$Events的思路一样,先定义一个接口来描述你的自定义事件,比如表单验证场景的两个事件:

// 自定义事件接口,对应组件里的$$Events
interface ValidationEvents {
  // 验证成功事件,携带解析后的数据
  validateSuccess: CustomEvent<{ data: Record<string, unknown> }>;
  // 验证失败事件,携带字段错误信息
  validateError: CustomEvent<{ errors: Record<string, string[]> }>;
}

3. 给Action绑定类型

在定义Action函数时,通过ActionReturn的泛型参数指定选项类型和事件类型,第三个泛型参数就是我们刚才定义的事件接口:

// 定义Action接收的选项类型
type ValidationActionOptions = {
  schema: ZodSchema;
};

export function validate(
  node: HTMLElement,
  options: ValidationActionOptions
): ActionReturn<ValidationActionOptions, ValidationEvents> {
  // 表单提交处理逻辑
  function handleSubmit(e: SubmitEvent) {
    e.preventDefault();
    const formData = new FormData(node as HTMLFormElement);
    const data = Object.fromEntries(formData);
    const result = options.schema.safeParse(data);
    
    if (result.success) {
      // 派发验证成功事件
      node.dispatchEvent(new CustomEvent('validateSuccess', { detail: { data: result.data } }));
    } else {
      // 派发验证失败事件
      node.dispatchEvent(new CustomEvent('validateError', { detail: { errors: result.error.flatten().fieldErrors } }));
    }
  }

  node.addEventListener('submit', handleSubmit);

  return {
    update(newOptions) {
      options = newOptions;
    },
    destroy() {
      node.removeEventListener('submit', handleSubmit);
    }
  };
}

4. 组件中使用时的类型提示

现在在Svelte组件里使用这个Action,监听自定义事件时VSCode会自动给出正确的类型提示,不会再出现无意义的波浪线:

<script lang="ts">
  import { validate } from './validateAction';
  import { z } from 'zod';

  const loginSchema = z.object({
    email: z.string().email('请输入合法邮箱'),
    password: z.string().min(6, '密码至少6位')
  });

  function handleSuccess(e: CustomEvent<{ data: z.infer<typeof loginSchema> }>) {
    console.log('验证通过:', e.detail.data);
  }

  function handleError(e: CustomEvent<{ errors: Record<string, string[]> }>) {
    console.log('验证失败:', e.detail.errors);
  }
</script>

<form use:validate={{ schema: loginSchema }} on:validateSuccess={handleSuccess} on:validateError={handleError}>
  <input type="email" name="email" placeholder="邮箱" />
  <input type="password" name="password" placeholder="密码" />
  <button type="submit">登录</button>
</form>

补充说明

  • ActionReturn的三个泛型参数依次是:Action选项类型、绑定的元素类型(可选,默认HTMLElement)、自定义事件类型(就是我们声明的事件接口)
  • 如果你的Action不需要接收选项,可以用Action<never, ValidationEvents>来简化类型声明
  • 自定义事件的detail类型要和CustomEvent的泛型严格对应,这样派发和监听时都会有精准的类型提示

内容的提问来源于stack exchange,提问作者JP Calvo

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.08.01 21:55:42