Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Flow: HTMLVideoElement and HTMLElement

I'm using Flow to typecheck my app.

I have a dom node I have to pull manually using document.querySelector. In Flow's eyes, this returns an HTMLElement. It's actually returning a video element, which I typecheck as HTMLVideoElement.

I'm trying to cast it, but it still errors out. What am I doing wrong?

let videoElement: HTMLVideoElement;
videoElement = document.querySelector('video') // type is HTMLElement, errors out.
<video class="lol"></video>

The error I get is This type is incompatible with HTMLVideoElement.

like image 463
RandallB Avatar asked Oct 18 '25 07:10

RandallB


1 Answers

Your error is unrelated to the fact that it is a video. If you look at the type definition for querySelector('video'), it is

querySelector(selector: 'video'): HTMLVideoElement | null;

which if you look closely, is incompatible with the type you've put on your variable. querySelector can return null and you are ignoring that fact. Flow is catching a potential bug here and making you verify and handle the buggy case, which is its entire job.

So you have a few options

  1. Annotate it with null and check when you use the variable to handle it, e.g.

    let videoElement: HTMLVideoElement | null  = document.querySelector('video');
    
  2. Explicitly check and throw so flow can know that you want it to error, e.g.

    let result = document.querySelector('video');
    if (!result) throw new Error("Video not found");
    
    // Technically you don't need to reassign and you can reuse 
    // 'result' but I'm doing it for clarity.
    let videoElement: HTMLVideoElement = result;
    
  3. Tell Flow you 100% sure it will always find the video by using any

    let videoElement: HTMLVideoElement = (document.querySelector('video'): any);
    
  4. Explicitly tell flow to ignore errors on that line. In your .flowconfig do

    [options]
    suppress_comment= \\(.\\|\n\\)*\\$FlowIgnore
    

    then in your code do

    let videoElement: HTMLVideoElement;
    
    // $FlowIgnore
    videoElement = document.querySelector('video');
    
like image 116
loganfsmyth Avatar answered Oct 20 '25 15:10

loganfsmyth