Closed3

`Property 'foo' does not exist on type 'HTMLElement'.` の解決方法

堀口セイト堀口セイト

TypeScriptで下記のようなコードを書いていました。

const blob = new Blob([response.data], { type: "application/zip" });
const url = window.URL.createObjectURL(blob);
const a = document.createElement("a");
a.href = url;
a.download = "files.zip";
document.body.appendChild(a);
window.URL.revokeObjectURL(url);
document.body.removeChild(a);

ファイルをzip化してユーザーにダウンロードさせる処理なんですが、まあ今回取り上げたいのはこの部分...

const a = document.createElement("a");
document.body.appendChild(a);

DOM要素を生成して<body>に追加する部分です。
こうした処理は結構よくあるコードじゃないでしょうか。
しかしここで問題発生。TypeScriptのエラーが出ました。

Property 'appendChild' does not exist on type 'HTMLElement'.

「HTMLElement型のオブジェクト(ここではdocument.body)に対してappendChildでアクセスしようとしたが、document.bodyにはappendChildというプロパティやメソッドは存在しません」という趣旨のエラーです。いやそんなわけ...

堀口セイト堀口セイト

結論から言うとappendChild()をやめてappend()にしたら解決しました。

document.body.appendChild(a); //NG
document.body.append(a); //OK

append ってjQueryにそんなメソッドあったな、って感じでしたが現在のJSには標準で備わっているメソッドでした。
MDNによれば違いは下記の様

  • append() は文字列も追加することができるが、appendChild() はNode オブジェクトのみを受け付ける。
  • append() に返り値はないが、appendChild() は追加された Node オブジェクトを返す。
  • append() は複数のノードや文字列を追加することができるが、appendChild() はノードを 1 つだけしか追加することができない。
    https://developer.mozilla.org/ja/docs/Web/API/Node/appendChild

全体的にappendの方が強力ですね。
にしたって今回は明らかにNode オブジェクトを1つだけしか渡していないのでエラーになる理由が謎ですが...

堀口セイト堀口セイト

ちなみにほか色々ChatGPTさんに聞いて試したけど全滅でした。
↓試したこと

  • anyやHTMLElementでキャストする
  • if(document?body){ ... }で囲う
  • node_modulesの再インストール
  • tsconfig.jsonの設定を変える
  • IDEの再起動

全部試したけど解決せず、最終的にコミュニティに問い合わせろと言われる始末。
ググっても同様に解決方法は発見できず。
appendChild()のまま解決することは無理なのかも。

このスクラップは1ヶ月前にクローズされました