Next.js项目TypeScript构建时FlowPlayer事件类型扩展问题咨询
FlowPlayer CDN引入后的TypeScript类型修复方案
现有代码的核心错误
- 自定义
FlowPlayerEvent时设置了T extends EventTarget的泛型约束,却没有给泛型设置默认值,直接裸用该类型就会触发Generic type 'FlowPlayerEvent' requires 1 type argument(s)的缺参报错 - 属性挂载逻辑完全错配:原代码写了
const Event: FlowPlayerEvent = ev.target;,把事件的DOM目标节点当成了扩展过的事件对象。实际上FlowPlayer会把currentTime/duration等属性直接挂在事件实例ev本身,ev.target只是普通的原生DOM元素,没有这些播放器属性——这也是初始时报Property 'currentTime' does not exist on type 'EventTarget & HTMLInputElement'的根本原因 - 类型标注不规范:定义类型时使用了大写的
Number/Object(TS里这俩是内置包装对象,不是原始值类型),既不符合TS编码规范,也无法识别opts.metadata.id这类嵌套属性的类型
正确的类型实现
1. 优化自定义事件类型定义
给泛型设置默认值,避免强制传参;修正属性所属位置,替换为正确的原始值类型,补充嵌套结构定义:
// 泛型默认值设为基础EventTarget,裸用不需要额外传参 type FlowPlayerEvent<T extends EventTarget = EventTarget> = Event & { // FlowPlayer挂载在事件本体的扩展属性 currentTime: number; duration: number; opts: { metadata: { id: string | number; [key: string]: any; }; [key: string]: any; }; // 保留原生事件的target属性,泛型对应target的具体类型 target: T; };
2. 修正事件处理函数的类型引用逻辑
去掉错误的ev.target类型赋值,直接将入参ev指定为FlowPlayerEvent类型,读取扩展属性时直接从ev上获取:
// 因为给泛型设置了默认值,这里不需要额外传入类型参数 function stateHandler(ev: FlowPlayerEvent) { if (ev.type === 'pause') { console.log('paused'); } if (ev.type === 'playing') { console.log(`Playing at ${ev.currentTime}, duration is: ${ev.duration}, video ID is: ${ev.opts.metadata.id}`); } if (ev.type === 'timeupdate') { console.log(ev.currentTime); } if (ev.type === 'ended') { console.log('The end'); } }
扩展适配场景
如果需要明确事件绑定的DOM元素类型,可在使用时传入对应的泛型实参,比如确认事件绑定的是HTMLVideoElement容器:
function stateHandler(ev: FlowPlayerEvent<HTMLVideoElement>) { // 此时ev.target会自动推导为HTMLVideoElement类型,不会再误匹配成HTMLInputElement }
内容的提问来源于stack exchange,提问作者Luiz Gustavo
相关产品推荐
相关产品推荐

