ちゃんと区別できてなくて、地味に誤解してたことに気付いたのでメモしておく。
それぞれの役割
@typescript-eslint/parser@typescript-eslint/typescript-estree
最初はestreeのほうが表向きのパッケージで、内部的にparserを使ってるのかと思ってたけど、まったくの逆だった。
parserこそがESLintのための表向きのパッケージで、純粋にASTだけ取り出したい場合は、typescript-estreeのほうをそのまま使えばよさそう。
parser側のコード
2つの関数がexportされてる。
parseForESLint()parse()
で、parseForESLint()のここで、typescript-estreeのparseAndGenerateServices()を呼び出すことで、ASTを作ってる。
そもそもparserのほうのパッケージは中身が薄くて、200行くらいしかない。
ASTのパース以外には、scope-managerでスコープ解析したりもしてる。
typescript-estree側のコード
(わかりにくいことに)こっちも2つの関数をexportしてる。
parseAndGenerateServices()parse()
まずparse()だが、こっちはparseWithNodeMapsInternal().astを返すだけで、いたってシンプル。
ts.createSourceFile()でTSのASTを生成しastConverter()でESTree互換に調整- それを返すだけ
注意点として、parse()のほうでは、errorOnTypeScriptSyntacticAndSemanticIssuesオプションが使えない。
つまりTSCが拾った構文エラーは検知できるけど、意味論的なエラーは検知できないってこと。このオプションを有効にしたい場合は、parseAndGenerateServices()のほうを使えっていうエラーになる。
つぎにparseAndGenerateServices()では、parse()で返すASTに加えて、TSのProgramを作ってる。
そのおかげで、意味論的なエラーまでも検知することができてるってわけ。
まとめ
@typescript-eslintでは、parserとtypescript-estreeパッケージから、それぞれ以下4種類のパース関数でASTを取得できる。
typescript-estreeにあるもののほうが、よりプリミティブな用途になってて、
typescript-estree/parse()- 構文エラーあり、意味論的エラーなし
typescript-estree/parseAndGenerateServices()- 構文エラーあり、意味論的エラーあり(オプションで有効化)
parserにあるのはtypescript-estreeのラッパーでしかなく、
parser/parseForESLint()parseAndGenerateServices()を呼びつつ、スコープ解析なんかもやる- しかし意味論的エラーなし
parser/parse()parseForESLint().astを返すだけ- よって意味論的エラーなし
という感じ。
ということを、Prettierのtypescriptパーサーが有効にしてるsuppressDeprecatedPropertyWarningsというオプションを追うために調べてた。
ちなみにPrettierのtypescriptパーサーでは、最もプリミティブなtypescript-estree/parse()が使われてる。