LoginSignup
1

More than 5 years have passed since last update.

typescriptで Property 'content' does not exist on type 'HTMLElement'. が出るとき

Last updated at Posted at 2018-02-13

要約

  • jqueryで取得したmetaタグからcontentの値をts上で取得するには
  • (<HTMLMetaElement>$('meta[name="csrf-token"]')[0]).contentみたいにキャストすると良いよ

詳細

Railsからajax通信をする時、csrf-tokenをheaderにつけて送ってあげることがままある。

その際にはmetaタグからcsrf-tokenを取得していたが、typescriptへの移行に伴い次のエラーが出るようになった。むむ。

ERROR in ./commons/api.ts
[tsl] ERROR in /path/to/issus/issus/app/assets/javascripts/commons/api.ts(65,46)
      TS2339: Property 'content' does not exist on type 'HTMLElement'.

該当箇所のコードがこちら

api.ts
export default class API {

  // 中略

  private static getRailsToken (): string {
    return $('meta[name="csrf-token"]')[0].content // ← ココ
  }

  // 中略

}

どうやら $('meta[name="csrf-token"]')[0]HTMLElementという型であり、そこにcontentというプロパティが無いらしい。

HTMLElementのインターフェースを見てみると

lib.d.ts
interface HTMLElement extends Element {
    accessKey: string;
    readonly children: HTMLCollection;
    contentEditable: string;
    readonly dataset: DOMStringMap;
    dir: string;
    draggable: boolean;
    hidden: boolean;
    hideFocus: boolean;
    innerText: string;
    readonly isContentEditable: boolean;
    lang: string;
    readonly offsetHeight: number;
    readonly offsetLeft: number;
    readonly offsetParent: Element;
    readonly offsetTop: number;
    readonly offsetWidth: number;
    onabort: (this: HTMLElement, ev: UIEvent) => any;
    onactivate: (this: HTMLElement, ev: UIEvent) => any;
    onbeforeactivate: (this: HTMLElement, ev: UIEvent) => any;
    onbeforecopy: (this: HTMLElement, ev: ClipboardEvent) => any;
    onbeforecut: (this: HTMLElement, ev: ClipboardEvent) => any;
    onbeforedeactivate: (this: HTMLElement, ev: UIEvent) => any;
    onbeforepaste: (this: HTMLElement, ev: ClipboardEvent) => any;
    onblur: (this: HTMLElement, ev: FocusEvent) => any;
    oncanplay: (this: HTMLElement, ev: Event) => any;
    oncanplaythrough: (this: HTMLElement, ev: Event) => any;
    onchange: (this: HTMLElement, ev: Event) => any;
    onclick: (this: HTMLElement, ev: MouseEvent) => any;
    oncontextmenu: (this: HTMLElement, ev: PointerEvent) => any;
    oncopy: (this: HTMLElement, ev: ClipboardEvent) => any;
    oncuechange: (this: HTMLElement, ev: Event) => any;
    oncut: (this: HTMLElement, ev: ClipboardEvent) => any;
    ondblclick: (this: HTMLElement, ev: MouseEvent) => any;
    ondeactivate: (this: HTMLElement, ev: UIEvent) => any;
    ondrag: (this: HTMLElement, ev: DragEvent) => any;
    ondragend: (this: HTMLElement, ev: DragEvent) => any;
    ondragenter: (this: HTMLElement, ev: DragEvent) => any;
    ondragleave: (this: HTMLElement, ev: DragEvent) => any;
    ondragover: (this: HTMLElement, ev: DragEvent) => any;
    ondragstart: (this: HTMLElement, ev: DragEvent) => any;
    ondrop: (this: HTMLElement, ev: DragEvent) => any;
    ondurationchange: (this: HTMLElement, ev: Event) => any;
    onemptied: (this: HTMLElement, ev: Event) => any;
    onended: (this: HTMLElement, ev: MediaStreamErrorEvent) => any;
    onerror: (this: HTMLElement, ev: ErrorEvent) => any;
    onfocus: (this: HTMLElement, ev: FocusEvent) => any;
    oninput: (this: HTMLElement, ev: Event) => any;
    oninvalid: (this: HTMLElement, ev: Event) => any;
    onkeydown: (this: HTMLElement, ev: KeyboardEvent) => any;
    onkeypress: (this: HTMLElement, ev: KeyboardEvent) => any;
    onkeyup: (this: HTMLElement, ev: KeyboardEvent) => any;
    onload: (this: HTMLElement, ev: Event) => any;
    onloadeddata: (this: HTMLElement, ev: Event) => any;
    onloadedmetadata: (this: HTMLElement, ev: Event) => any;
    onloadstart: (this: HTMLElement, ev: Event) => any;
    onmousedown: (this: HTMLElement, ev: MouseEvent) => any;
    onmouseenter: (this: HTMLElement, ev: MouseEvent) => any;
    onmouseleave: (this: HTMLElement, ev: MouseEvent) => any;
    onmousemove: (this: HTMLElement, ev: MouseEvent) => any;
    onmouseout: (this: HTMLElement, ev: MouseEvent) => any;
    onmouseover: (this: HTMLElement, ev: MouseEvent) => any;
    onmouseup: (this: HTMLElement, ev: MouseEvent) => any;
    onmousewheel: (this: HTMLElement, ev: WheelEvent) => any;
    onmscontentzoom: (this: HTMLElement, ev: UIEvent) => any;
    onmsmanipulationstatechanged: (this: HTMLElement, ev: MSManipulationEvent) => any;
    onpaste: (this: HTMLElement, ev: ClipboardEvent) => any;
    onpause: (this: HTMLElement, ev: Event) => any;
    onplay: (this: HTMLElement, ev: Event) => any;
    onplaying: (this: HTMLElement, ev: Event) => any;
    onprogress: (this: HTMLElement, ev: ProgressEvent) => any;
    onratechange: (this: HTMLElement, ev: Event) => any;
    onreset: (this: HTMLElement, ev: Event) => any;
    onscroll: (this: HTMLElement, ev: UIEvent) => any;
    onseeked: (this: HTMLElement, ev: Event) => any;
    onseeking: (this: HTMLElement, ev: Event) => any;
    onselect: (this: HTMLElement, ev: UIEvent) => any;
    onselectstart: (this: HTMLElement, ev: Event) => any;
    onstalled: (this: HTMLElement, ev: Event) => any;
    onsubmit: (this: HTMLElement, ev: Event) => any;
    onsuspend: (this: HTMLElement, ev: Event) => any;
    ontimeupdate: (this: HTMLElement, ev: Event) => any;
    onvolumechange: (this: HTMLElement, ev: Event) => any;
    onwaiting: (this: HTMLElement, ev: Event) => any;
    outerText: string;
    spellcheck: boolean;
    readonly style: CSSStyleDeclaration;
    tabIndex: number;
    title: string;
    blur(): void;
    click(): void;
    dragDrop(): boolean;
    focus(): void;
    msGetInputContext(): MSInputMethodContext;
    addEventListener<K extends keyof HTMLElementEventMap>(type: K, listener: (this: HTMLElement, ev: HTMLElementEventMap[K]) => any, useCapture?: boolean): void;
    addEventListener(type: string, listener: EventListenerOrEventListenerObject, useCapture?: boolean): void;
}

ほんとだ。たしかに無い。

そこで勘(エディタ補完)に頼って型キャストしてみると<HTMLMetaElement>が見つかったので今度はそのインターフェースを覗いてみる。

lib.d.ts
interface HTMLMetaElement extends HTMLElement {
    /**
      * Sets or retrieves the character set used to encode the object.
      */
    charset: string;
    /**
      * Gets or sets meta-information to associate with httpEquiv or name.
      */
    content: string;
    /**
      * Gets or sets information used to bind the value of a content attribute of a meta element to an HTTP response header.
      */
    httpEquiv: string;
    /**
      * Sets or retrieves the value specified in the content attribute of the meta object.
      */
    name: string;
    /**
      * Sets or retrieves a scheme to be used in interpreting the value of a property specified for the object.
      */
    scheme: string;
    /**
      * Sets or retrieves the URL property that will be loaded after the specified time has elapsed. 
      */
    url: string;
    addEventListener<K extends keyof HTMLElementEventMap>(type: K, listener: (this: HTMLMetaElement, ev: HTMLElementEventMap[K]) => any, useCapture?: boolean): void;
    addEventListener(type: string, listener: EventListenerOrEventListenerObject, useCapture?: boolean): void;
}

無事contentを発見できた。ということで変更後のコードがこちら

api.ts
export default class API {

  // 中略

  private static getRailsToken (): string {
    return (<HTMLMetaElement>$('meta[name="csrf-token"]')[0]).content
  }

  // 中略

}

無事tscも通過しめでたし。

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
1