鈴木颯介のブログ

技術的なメモとかポエムとか。

Prettier の TypeScript 3.7 で追加される新しい構文のサポートの現状と今後

TypeScript 3.7 の beta 版が公開されてから 3 週間ほど立ちました。この 3 週間、TwitterGitHub の Issue 上で、Prettier が TS 3.7 beta の新しい構文をサポートしていないことについて言及しているのを目にすることが多々あったので、状況を解説してみます。

まず、TypeScript 3.7 で追加される新しい構文は(おそらく)、Optional Chaining、Nullish Coalescing、Assertion Functions、あと class の declare field の 4 種類があります。(それぞれの詳細は https://devblogs.microsoft.com/typescript/announcing-typescript-3-7-beta/https://github.com/microsoft/TypeScript/pull/33509 を読んでください。)

現状

Prettier は 受け取ったソースを外部のパーサーでパースした結果の AST を見てフォーマットをしますが、Prettier の現在の最新バージョンである 1.18.2 の依存している TypeScript パーサー(の Prettier が依存しているバージョン)はこれら 4 つの構文をサポートしていないので、Prettier はこれらに対応できていません。

今後

大きく分けて 2 つの対応がされると思います。

babel-ts パーサーによる対応

Prettier は 1.19 から(おそらく) babel-ts というパーサーオプションを追加します。( https://github.com/prettier/prettier/pull/6400 ) これによって babel/parser を使って TypeScript をパースできるようになります。babel/parser は、いまのところ Optional Chaining、Nullish Coalescing をサポートしていて、Assertion Functions も対応中 ( https://github.com/babel/babel/pull/10543 )なので、 TS 3.7 で追加される構文についてもほとんどサポートできるでしょう。(デフォルトではないので、 parser オプションに babel-ts を指定する必要はあります)

実際、現在 Prettier は JavaScript のパースには babel/parser を使っているので、JavaScript のフォーマットでは Optional Chaining と Nullish Coalescing を使うことができます。( https://prettier.io/playground/#N4Igxg9gdgLgprEAuEAzVACA-FjAjPAbgB0p0sA6AwkAGhAgAcYBLaAZ2VAEMAnXiAHcACnwScU3AG4QWAEzog8vbmADWcGAGVGqllADmyGLwCucegAsYAWwA2AdUst47XWDhbxLllJcBPZHB2Tnp9djheGGEVAxtuZFRuOwj6ACt2AA8AIRV1TS1uGzgAGX04ROTUkAzMrX0DOzgARVMIeEqUixBdXgjeILxuPDg7RUZefRgHeRhLZAAOAAZ6CYgIhxVGIIm4fqkK+gBHNvgYpgkQbnYAWig4ODlHxV44E5ZXmO44hKQkrvoERsLGMZm67AaTVa7Qqfyq3RgwxmcjmyAATPQTNwWHYGgBhCA2eJBKDQQ4gUwRAAqwwk-wiAF8GUA )

余談ですが、もしかしたら今後 Prettier が使うデフォルトの TypeScript パーサーがbabel-tsに置き換わるかもしれません( https://github.com/prettier/prettier/issues/4103 )

typescript-estree のアップグレードによる対応

Prettier 1.18.2 では、TypeScript フォーマットのためのパーサーに、typescript-eslint の typescript-estree を使っています。そして typescript-estree の最新版は Optional Chaining、Nullish Coalescing、Assertion Functions に対応しています。( https://github.com/typescript-eslint/typescript-eslint/pull/1045 )

なので、Prettier が依存している typescript-estree のバージョンを最新まであげれば対応できるんですが、もうひとつ問題がでてきます。

Prettier は Node@6 をサポートしているのですが、 typescript-estree の最新版は Node@6 のサポートをしていません。なので、Prettier は typescript-estree の最新版を使うために Node@6 をドロップする必要があり、そのためにメジャーバージョンアップをする必要があります。しかし、そのためには他の色々なタスクをやらないといけなくて時間がかかってしまいます。

なので、現在主に2つのアプローチが検討されています。

がんばります

自分以外のメンテナーも色々考えていて、状況もすぐ変わっていくと思うんですが、2019/10/22 現在ではこんな雰囲気ですというくらいで捉えておいてもらえるといいかなと思います。