経験は何よりも饒舌

10年後に真価を発揮するかもしれないブログ 

npmから@typesを使う場合はDefinitelyTypedを見に行かないといけないことがある

Link Preview JSという、「allows you to extract information from a HTTP url/link (or parse a HTML document) and retrieve meta information such as title, description, images, videos, etc」なレポジトリがあった。

github.com

そこでは、cheerioというライブラリを用いて、パースされたレスポンスから特定の要素を取得している。
https://github.com/ospfranco/link-preview-js/blob/d22888f26718674d7a32cfb935434f7357c80817/index.ts#L236

Link Preview JSはTypeScriptで書かれているのだが、cheerioに対する型が全くなく、anyが使用されていたので、@types/cheerioを導入した。

github.com

だが、一部だけ以下のようなエラーがでて、@types/cheerioを用いてもanyが残ってしまっていた。

Property 'attribs' does not exist on type 'Element'.
Property 'attribs' does not exist on type 'TextElement'. ts(2339)

https://github.com/ospfranco/link-preview-js/pull/83#discussion_r563268635


このまま放置するのも気持ちが悪かったので、実際に@types/cherrioの型が書かれているDefinitely Typedをみにいった。

github.com
DefinitelyTyped/types/cheerio at master · DefinitelyTyped/DefinitelyTyped · GitHub

すると、cheerio.ElementTagElementにのみattribsの型が定義されていることがわかった。
https://github.com/DefinitelyTyped/DefinitelyTyped/blob/68e48c5ad46f0e7733feace0a9120d7dc3108462/types/cheerio/index.d.ts#L33

テストを見ても、elementtypetextではない、つまり、TextElementではなくTagElementであることを確認している。
https://github.com/DefinitelyTyped/DefinitelyTyped/blob/b41bbafcd298b4b2aaa851d43ffadb6ef3565e69/types/cheerio/cheerio-tests.ts#L347

なので、それを適用して、自分で作ったanyを回収しにいった。
github.com

src/@types/*d.tsに型定義があるのと比べて、npmでインストールした場合は、node_modules/@types/*/*d.tsに型定義が隠蔽されてしまうので、便利だけど難しいなと思う。
それを解消する何かがもうすでにあるのだろうか。



TwitterでこのOSSの作者から感謝してもらえた。
https://twitter.com/ospfranco/status/1353312260823855105

(フォローしたけどフォローは返ってこなかった)