@brightcove/react-player-loader のTypeScript型定義

ChatGPT o3を問い詰めて、表題の定義を作ってみた。一応良好に動いています。
コピペしてsrc/types/BrightcovePlayerLoader.d.tsを作成してください

# 日本語コメント版

[@brightcove/react‑player‑loader](https://www.npmjs.com/package/@brightcove/react-player-loader) (version 1.5.0)に対応した型定義です。自己責任でご利用ください。（記載コメントに間違いがあっても責任取れません。）  
あと、当型定義は[@types/video.js](https://www.npmjs.com/package/@types/video.js)に依存しているため、こちらを先に導入してください。

``` src/types/BrightcovePlayerLoader.d.ts 
/**
 * Brightcove React Player Loader 用 TypeScript 型定義
 *
 * - 公式ドキュメント (Player Loader v8.6) とソースを調査して作成
 * - `any` を排除し、どうしても自由度が必要な箇所のみ `unknown` を使用
 * - Video.js v8 (`@types/video.js`) を前提にしているため、
 *   `npm i -D video.js @types/video.js` を推奨
 * - インラインコメントに Brightcove の仕様を日本語で明記
 */
declare module '@brightcove/react-player-loader' {
  import * as React from 'react';
  import videojs from 'video.js';

  /** 埋め込み方法 */
  export type BrightcoveEmbedType = 'in-page' | 'iframe';

  /** responsive オプション詳細 */
  export interface BrightcoveResponsiveOption {
    /** アスペクト比 (例: '4:3' / '16:9' ※デフォルト16:9) */
    aspectRatio?: string;
    /**
     * iframe / 横スワイプ型プレイリストを利用する際の高さ計算調整
     * (iframe 埋め込み時のみ有効)
     */
    iframeHorizontalPlaylist?: boolean;
    /** 最大幅を CSS 単位で指定 (例: '960px') */
    maxWidth?: string;
  }

  /** embedOptions ― Brightcove 固有の追加 DOM 生成フラグ */
  export interface BrightcoveEmbedOptions {
    /**
     * Picture‑in‑Picture DOM ラッパを生成
     * v6.14 以降 + PiP プラグイン必須
     */
    pip?: boolean;
    /**
     * Playlist UI DOM を挿入
     * true   : `<div class="vjs-playlist">` (最新推奨)
     * {legacy:true}: `<ul>` 形式 (旧 UI)
     */
    playlist?: boolean | { legacy?: boolean };
    /**
     * 親幅に合わせてレスポンシブ化 (インページ時のみ)
     * true  : 16:9 ラッパ生成
     * object: BrightcoveResponsiveOption で詳細指定
     */
    responsive?: boolean | BrightcoveResponsiveOption;
    /** タグ名を video-js / video から選択 (デフォルト video-js) */
    tagName?: 'video-js' | 'video';
    /** 非 minify 版プレーヤー JS を読み込み (デバッグ用) */
    unminified?: boolean;
  }

  /** 「成功」コールバックに渡される discriminated union 型 */
  export type BrightcovePlayerLoaderSuccess =
    | { type: 'in-page'; ref: videojs.Player }
    | { type: 'iframe'; ref: HTMLIFrameElement };

  /**
   * BrightcovePlayerLoaderOptions
   * → Brightcove Player Loader にそのまま渡るオプション
   * ※ embedType='iframe' の場合、`options` は無視される
   */
  export interface BrightcovePlayerLoaderOptions {
    /** Brightcove アカウント ID (必須) */
    accountId: string | number;
    /** Brightcove プレーヤー ID (省略時 'default') */
    playerId?: string;
    /** Brightcove 埋め込み ID (省略時 'default') */
    embedId?: string;
    /** Video Cloud ビデオ ID / 参照 ID */
    videoId?: string | number;
    /** Video Cloud プレイリスト ID / 参照 ID */
    playlistId?: string | number;
    /** playlistId 指定時、再生開始するビデオ ID */
    playlistVideoId?: string | number;

    /**
     * Catalog Search
     * 文字列 → キーワード検索
     * オブジェクト → Catalog API の検索条件
     * (詳細 API 型が多岐にわたるため unknown で許容)
     */
    catalogSearch?: string | Record<string, unknown>;
    /**
     * Catalog Sequence
     * 配列 or オブジェクトで Lazy Sequence 指定
     */
    catalogSequence?: unknown[] | Record<string, unknown>;

    /** SSAI 広告設定 ID */
    adConfigId?: string;
    /** Brightcove Application ID (任意) */
    applicationId?: string;
    /** Dynamic Delivery ルール ID */
    deliveryConfigId?: string;

    /** 埋め込み方法 (デフォルト 'in-page') */
    embedType?: BrightcoveEmbedType;
    /** 上記 BrightcoveEmbedOptions を参照 */
    embedOptions?: BrightcoveEmbedOptions;

    /**
     * Video.js プレーヤー初期化オプション
     * - Brightcove Studio の設定より優先
     * - plugins 設定もここで渡す
     * - iframe 埋め込み時は無視される
     */
    options?: videojs.PlayerOptions;

    /** 独自ホストしたプレーヤー JS への URL */
    playerUrl?: string;
    /** ポスター (Brightcove 返却サムネを上書き) */
    poster?: string;

    /** プレーヤーロード成功時 */
    onSuccess?: (success: BrightcovePlayerLoaderSuccess) => void;
    /** プレーヤーロード失敗時 */
    onFailure?: (error: Error) => void;
    /** `<video-js>` または `<iframe>` 挿入直前のフック */
    onEmbedCreated?: (element: Element) => void;
  }

  /**
   * BrightcovePlayerLoaderProps
   * - React ラッパー固有の追加パラメータを混在
   */
  export interface BrightcovePlayerLoaderProps
    extends BrightcovePlayerLoaderOptions {
    /**
     * ベース URL 上書き (例: プレーヤー JS を別 CDN から取得)
     * 通常は指定不要
     */
    baseUrl?: string;
    /** コンテナ DIV へ付与する任意属性 */
    attrs?: React.HTMLAttributes<HTMLDivElement>;
    /**
     * true にすると props 変更時にプレーヤーを自動 dispose / reload せず、
     * 手動で `loadPlayer()` 呼び出しが必要となる
     */
    manualReloadFromPropChanges?: boolean;
  }

  /**
   * React コンポーネント本体
   * - `player` プロパティに初期化済みプレーヤー参照を保持
   *   (in‑page → videojs.Player, iframe → HTMLIFrameElement)
   * - 手動リロード用に `loadPlayer()` を公開
   */
  const BrightcovePlayerLoader: React.FC<BrightcovePlayerLoaderProps> & {
    /** 手動ロード補助メソッド (インスタンスメソッドではなく静的 util) */
    loadPlayer?: () => void;
    /** 現在読み込まれているプレーヤー参照 (読み取り専用) */
    player?: videojs.Player | HTMLIFrameElement;
  };

  export default BrightcovePlayerLoader;
}

```



# 英語コメント版 (English comment version)

I used ChatGPT o3 to generate TypeScript definitions for the npm package [@brightcove/react‑player‑loader](https://www.npmjs.com/package/@brightcove/react-player-loader) (version 1.5.0). They target TypeScript v5. Feel free to use them, but do so at your own discretion.  
Please note that these type definitions depend on [@types/video.js](https://www.npmjs.com/package/@types/video.js).

``` src/types/BrightcovePlayerLoader.d.ts
/**
 * TypeScript definitions for Brightcove React Player Loader
 *
 * - Created from Player Loader v8.6 docs and source
 * - Avoids `any`; only uses `unknown` where an open shape is unavoidable
 * - Assumes Video.js v8 typings (`npm i -D video.js @types/video.js`)
 * - All Brightcove‑specific behavior is documented inline
 */
declare module '@brightcove/react-player-loader' {
  import * as React from 'react';
  import videojs from 'video.js';

  /** Supported embed types */
  export type BrightcoveEmbedType = 'in-page' | 'iframe';

  /** Detailed options for responsive wrapper */
  export interface BrightcoveResponsiveOption {
    /** Aspect ratio string, e.g. '4:3' (default: '16:9') */
    aspectRatio?: string;
    /** Adjust height when using iframe + horizontal playlist UI */
    iframeHorizontalPlaylist?: boolean;
    /** Max width of the player wrapper, any CSS length */
    maxWidth?: string;
  }

  /** embedOptions — DOM helpers injected by Player Loader */
  export interface BrightcoveEmbedOptions {
    /** Insert PiP wrapper (requires PiP plugin, player ≥ 6.14) */
    pip?: boolean;
    /**
     * Insert playlist UI wrapper.
     * `true` ⇒ modern `<div class="vjs-playlist">`
     * `{ legacy:true }` ⇒ legacy `<ul>` structure
     */
    playlist?: boolean | { legacy?: boolean };
    /**
     * Make player fluid‑responsive (in‑page only):
     * `true` ⇒ default 16:9 wrapper,
     * object ⇒ fine‑grained control via BrightcoveResponsiveOption
     */
    responsive?: boolean | BrightcoveResponsiveOption;
    /** Tag name for in‑page embed, default 'video-js' */
    tagName?: 'video-js' | 'video';
    /** Load unminified player JS (debug only) */
    unminified?: boolean;
  }

  /** Discriminated union for the success callback */
  export type BrightcovePlayerLoaderSuccess =
    | { type: 'in-page'; ref: videojs.Player }
    | { type: 'iframe'; ref: HTMLIFrameElement };

  /**
   * Options forwarded to Brightcove Player Loader.
   * Note: when `embedType === 'iframe'`, `options` is ignored.
   */
  export interface BrightcovePlayerLoaderOptions {
    /** Brightcove account ID (required) */
    accountId: string | number;
    /** Player ID (default 'default') */
    playerId?: string;
    /** Embed ID (default 'default') */
    embedId?: string;
    /** Video Cloud video ID or reference ID */
    videoId?: string | number;
    /** Video Cloud playlist ID or reference ID */
    playlistId?: string | number;
    /** Video ID within the above playlist to start from */
    playlistVideoId?: string | number;

    /**
     * Catalog search query.
     * string → keyword search,
     * object → full Catalog API params.
     */
    catalogSearch?: string | Record<string, unknown>;
    /**
     * Catalog sequence (lazy sequence).
     * Accepts array or object as defined by the Catalog API.
     */
    catalogSequence?: unknown[] | Record<string, unknown>;

    /** SSAI ad configuration ID */
    adConfigId?: string;
    /** Optional application ID forwarded to Brightcove */
    applicationId?: string;
    /** Dynamic Delivery rule ID */
    deliveryConfigId?: string;

    /** Embed method (default 'in-page') */
    embedType?: BrightcoveEmbedType;
    /** Extra DOM helpers; see BrightcoveEmbedOptions */
    embedOptions?: BrightcoveEmbedOptions;

    /**
     * Video.js player options (overrides Studio settings).
     * Includes `plugins` property for Video.js/Brightcove plugins.
     * Ignored when using iframe embed.
     */
    options?: videojs.PlayerOptions;

    /** Custom player JS URL (self‑hosted builds) */
    playerUrl?: string;
    /** Poster image URL (overrides Brightcove thumbnail) */
    poster?: string;

    /** Called on successful load */
    onSuccess?: (success: BrightcovePlayerLoaderSuccess) => void;
    /** Called if loading fails */
    onFailure?: (error: Error) => void;
    /**
     * Invoked just before the `<video-js>` or `<iframe>` element
     * is inserted into the DOM. Returning an Element replaces the default.
     */
    onEmbedCreated?: (element: Element) => void;
  }

  /**
   * React component props —
   * Brightcove options plus wrapper‑specific extras.
   */
  export interface BrightcovePlayerLoaderProps
    extends BrightcovePlayerLoaderOptions {
    /** Override base URL for player assets (rarely needed) */
    baseUrl?: string;
    /** Attributes applied to the wrapper <div> */
    attrs?: React.HTMLAttributes<HTMLDivElement>;
    /**
     * If true, prop changes never auto‑reload the player.
     * Call `loadPlayer()` manually after updating props.
     */
    manualReloadFromPropChanges?: boolean;
  }

  /**
   * Component definition.
   * - `player` holds the live player reference:
   *   in‑page ⇒ videojs.Player, iframe ⇒ HTMLIFrameElement
   * - Exposes `loadPlayer()` for manual reloads.
   */
  const BrightcovePlayerLoader: React.FC<BrightcovePlayerLoaderProps> & {
    loadPlayer?: () => void;
    player?: videojs.Player | HTMLIFrameElement;
  };

  export default BrightcovePlayerLoader;
}

```