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

video.js 8.X.X在TypeScript React中引入第三方插件的类型错误问题

解决Video.js 8.x + TypeScript 第三方插件类型错误问题

问题场景

将集成Video.js及插件的jQuery应用迁移到TypeScript React时,使用Video.js 8.3.0版本,调用第三方插件方法(如player.playlist())时出现TS类型错误:Property 'playlist' does not exist on type 'Player',但实际生产环境功能正常。

核心原因

Video.js 8.x重构了类型系统,Player类型从video.js/dist/types/player子模块导出,而非7.x版本的根模块或VideoJsPlayer类型。之前针对7.x的类型扩展方案因模块路径不匹配失效。

解决方案

通过自定义.d.ts文件扩充Video.js Player接口的类型,步骤如下:

1. 创建自定义类型文件

在项目的类型目录(如src/types/)下创建videojs-plugins.d.ts,内容如下:

import type { Player } from 'video.js/dist/types/player';

// 扩充Player所在的子模块类型
declare module 'video.js/dist/types/player' {
  interface Player {
    // 匹配videojs-playlist插件的playlist方法重载
    playlist(): PlaylistItem[];
    playlist(items: PlaylistItem[]): void;
    playlist(index: number): PlaylistItem;

    // 定义playlist对象的子方法(如autoadvance)
    playlist: {
      autoadvance(delay: number): void;
      currentItem(): number;
      currentItem(index: number): void;
      next(): void;
      previous(): void;
    } & Player['playlist'];
  }
}

// 定义播放列表项的类型(可根据业务需求调整)
interface PlaylistItem {
  sources: Array<{
    src: string;
    type: string;
  }>;
  title?: string;
  poster?: string;
}

2. 配置TypeScript识别类型文件

确保tsconfig.json的include数组包含该类型文件:

{
  "include": [
    "src/**/*",
    "src/types/**/*.d.ts"
  ]
}

3. 业务代码无需修改

保持原有Player导入和调用逻辑即可,TS会自动识别扩展后的类型:

import { useRef, useEffect } from 'react';
import videojs from 'video.js';
import type Player from 'video.js/dist/types/player';
import 'videojs-playlist';

const VideoPlayer = () => {
  const playerRef = useRef<Player | null>(null);
  const playlist = [
    {
      sources: [{ src: 'video-url-1', type: 'video/mp4' }],
      title: '视频1'
    }
  ];

  useEffect(() => {
    if (!playerRef.current) {
      const videoElement = document.createElement('video-js');
      const player = videojs(videoElement, { controls: true });
      playerRef.current = player;
      
      player.playlist(playlist);
      player.playlist.autoadvance(0); // 不再报类型错误
    }

    return () => {
      if (playerRef.current) {
        playerRef.current.dispose();
        playerRef.current = null;
      }
    };
  }, []);

  return <div ref={el => el?.appendChild(playerRef.current?.el())} />;
};

export default VideoPlayer;

关键说明

  • 必须针对video.js/dist/types/player子模块扩充类型,而非根模块video.js,这是8.x版本与7.x的核心差异。
  • 可根据使用的其他Video.js插件,在同一个.d.ts文件中继续扩充Player接口的其他方法/属性。

内容的提问来源于stack exchange,提问作者Justin Garcia

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.07.11 04:53:33