简体   繁体   中英

Typescript “Property does not exists on type Element”

I'm starting my journey with Typescript. So I have video tag in my Html and in .ts file these lines:

...
class KomakhaPlayer {
  private container = ...;
  private video: Element = this.container.getElementsByClassName( 'video' )[ 0 ];
  private controls = ...;

  constructor(){
    this.video.controls = false; // ts error
    ...
  }
}
...

As you can see this.video has Element type, but below this.video.controls throws me a Typescript error Property 'controls' does not exists on type 'Element' .

Temporary I changed Element type to any , but I want to know how properly solve this error and handle similar in future. Thanks in advance!

SOLUTION: So the right approach is defining like this:

private video: HTMLVideoElement = <HTMLVideoElement>this.container.getElementsByClassName( 'video' )[ 0 ];

Explanation by @deceze below in comments

Element is a very generic root object which indeed does not have a controls attribute. See https://developer.mozilla.org/en-US/docs/Web/API/Element . What you're looking for is an HTMLVideoElement , which inherits from HTMLMediaElement , which has a controls attribute.

Typescript is entirely correct: you told it you're working with an Element , and Typescript warns you that an Element is not known to have controls .

Given your statement (emphasis mine)

So I have video tag in my Html and in .ts file these lines:

class KomakhaPlayer {
  private video: Element = this.container.getElementsByClassName('video')[0];    
  constructor(){
    this.video.controls = false; // ts error
  }
}

You have made two critical errors.

First or foremost, to get the correct runtime behavior you need to elements by their tag name . That is you use document.getElementsByTagName not document.getElementsByClassName .

Resolving this results in

class KomakhaPlayer {
  private video: Element = this.container.getElementsByTagName('video')[0];    
  constructor(){
    this.video.controls = false; // ts error
  }
}

And still, there is an error.

This is because of a critical misunderstanding. You've overspecified the types in your program, preventing the language from performing its highly sophisticated type inference. One you remove the : Element type annotation from the video field, you code works type checks because the compiler has more type information not less. Say less and get more.

class KomakhaPlayer {
  private video = this.container.getElementsByTagName('video')[0];    
  constructor(){
    this.video.controls = false;
  }
}

Playground Link

TypeScript is about having type information not type writing type annotations. Write type annotations where the compiler does not know what the types are or when you want to formalize an API, not when you are initializing a field.

This worked for me in my code.

const value = 'hello world';

const el: HTMLElement = document.getElementById('id_of_element') as HTMLElement;
el.innerHTML = value;

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM