TypeScript5.5がリリースされたので何ができるようになったのか確認する

先日TypeScript5.5がリリースされました。
バージョンアップについての情報をまだ確認できてなかったのでキャッチアップしていきます！

https://devblogs.microsoft.com/typescript/announcing-typescript-5-5/

## 追加された新機能
以下が5.5で追加された新規機能です。

- 型術語を推論する！
- `obj[key]`形式の式が絞り込める！
- JSDocで`@importタグ`が使える！
- 正規表現構文チェックできる！
- ECMAScriptの新しいSetメソッドのサポート！
- 独立した宣言
- 設定ファイルのテンプレート変数`${configDir}`
- package.json宣言ファイル生成の依存関係の参照
- エディターとウォッチモードの信頼性の向上
- パフォーマンスとサイズの最適化
- ECMAScriptモジュールからのAPIの利用が簡単
- APItranspileDeclarationについて

## 追加された新機能の概要
ざっくり概要を理解していきます！

### 型術語を推論する！

明示的な型述語を省略できるため、コードが直感的になり、読みやすくなりました。

:::note
配列から特定の条件を満たす要素を抽出する際に、TypeScriptが条件によって変数の型を自動的に推論できます。
:::

推論してくれる条件として以下の4点を満たしている必要があるとのことです。

1. 関数には明示的な戻り値の型または型述語がない
1. 関数に単一のreturnステートメントがあり、暗黙的な戻り値がない
1. 関数はパラメータを変更していない
1. 関数はboolean、パラメータの改良に関連付けられた式を返す

### `obj[key]`形式の式が絞り込める！
こんなのができるようになったそうです！

```typescript
function f1(obj: Record<string, unknown>, key: string) {
  if (typeof obj[key] === "string") {
    // 以前はエラーになっていた
    obj[key].toUpperCase();
  }
}
```

### JSDocで`@importタグ`が使える！

```typescript
/** @import { SomeType } from "some-module" */

/**
 * @param {SomeType} myValue
 */
function doSomething(myValue) {
    // ...
}
```

名前空間インポートも対応。

```typescript
/** @import * as someModule from "some-module" */

/**
 * @param {someModule.SomeType} myValue
 */
function doSomething(myValue) {
    // ...
}
```

### 正規表現構文チェックできる！
正規表現をチェックしてくれるようになったようです！

:::note alert
TypeScriptの正規表現のサポートは、正規表現リテラルに限定されていることに注意。
`new RegExp`文字列リテラルを使用して呼び出した場合、TypeScriptは指定された文字列をチェックしません…
:::

### ECMAScriptの新しいSetメソッドのサポート！

以前であれば下記のように`union`や`intersection`を利用するとエラーになっていました。

```typescript
let primaryColors = new Set(["red", "blue", "yellow"]);
let secondaryColors = new Set(["green", "orange", "purple"]);

console.log(primaryColors.union(secondaryColors));
console.log(primaryColors.intersection(secondaryColors));
```

- Error: Property 'union' does not exist on type 'Set<string>'
- Error: Property 'intersection' does not exist on type 'Set<string>'

のようなエラーが出ていたところが今回のアップデートでサポートされ利用できるようになりました。

### 分離した宣言
一番理解ができなかった項目でした…。
理解できたのは、宣言ファイル（.d.tsファイル）の生成プロセスを高速化し、並列ビルドを可能にする機能であることです。
ものレポ環境などの大規模プロジェクトでのビルド時間短縮を目的としているとのこと。

### 設定ファイルのテンプレート変数`${configDir}`
これまでtsconfig.jsonファイル内のすべてのパスがファイル自体の場所に対して相対的だったのを`${configDir}`を利用して記述できるようになりました。

```diff_typescript
{
  "compilerOptions": {
    "typeRoots": [
-      "./node_modules/@types"
-      "./custom-types"
+      "${configDir}/node_modules/@types"
+      "${configDir}/custom-types"
    ],
    "outDir": "dist"
  }
}
```

これにより拡張性や移植性が向上しました。

### [package.json宣言ファイル生成の依存関係の参照](https://devblogs.microsoft.com/typescript/announcing-typescript-5-5/#consulting-packagejson-dependencies-for-declaration-file-generation)
TypeScriptの宣言ファイル生成で、プログラムで明示的にインポートされたことのないファイルの内容で発見されるとエラーになっていましたが、こちらのエラーに対して寛容になったとのこと…。

:::note warn
この部分はあまり理解できてませんが、ちょっと厳格すぎたからルールをゆるくしたよーってことですかね…。
:::

### エディターとウォッチモードの信頼性の向上
TSServer/エディターの再起動回数が減るらしい！
具体的には…

- 設定ファイル内のエディターエラーを正しく更新する
- 削除後の即時書き込みの処理の改善
- 解決に失敗した場合、シンボリックリンクが追跡される
- プロジェクト参照は自動インポート

### パフォーマンスとサイズの最適化
パフォーマンスの最適化のために下記の対応がなされたとのことです。

- 言語サービスとパブリック API における単形化オブジェクト
- モノモーフィズム制御フローノード
- 制御フローグラフの最適化
- チェックインをスキップ
- TypeScriptパッケージサイズの削減
- 宣言出力におけるノードの再利用
- 判別ユニオンからのコンテキスト型のキャッシュ

### ECMAScriptモジュールからのAPIの利用が簡単
ユーザーは`Node.js`のECMAScriptモジュールで`TypeScript npm`パッケージからの名前付きインポートを使用できるようになりました。

```diff_typescript
- import { createSourceFile } from "typescript"; // ❌ error
+ import { createSourceFile } from "typescript"; // ✅ works now!

import * as ts from "typescript";
- ts.createSourceFile // ❌ undefined???
+ ts.createSourceFile // ✅ works now!
```

### `transpileDeclaration`というAPIについて
TypeScript5.5以前だと、transpileModuleというAPIがあります。
コードがオプションのエラーに違反すると、正しく生成されない可能性がある仕様でした。

新しいAPI`transpileDeclaration`は`transpileModule`と同様のAPIですが、
入力コードにエラーがない場合にのみ、正確な宣言ファイルが生成されるようになったようです。

## 注目すべき行動の変化
5.5のバージョン以前から変わった内容について確認していきます！

### TypeScript5.0で非推奨となった機能について
TypeScript5.0では以下の機能が非推奨になりました
- charset
- target: ES3
- importsNotUsedAsValues
- noImplicitUseStrict
- noStrictGenericChecks
- keyofStringsOnly
- suppressExcessPropertyErrors
- suppressImplicitAnyIndexErrors
- out
- preserveValueImports
- prepend in project references
- implicitly OS-specific newLine

TypeScript6.0で指定するとエラーになります。
廃止戦略は[こちら](https://github.com/microsoft/TypeScript/issues/51000)。

:::note warn
TypeScript5.0以降のバージョンで使用する場合は、`ignoreDeprecations`オプションで"5.0"を指定する必要があります。
:::

### lib.d.ts変更点

- `--isolatedDeclarations`コンパイラオプションの追加
    - エクスポートされたシンボル（関数、変数、クラスなど）に明示的な型注釈がない場合にエラーを報告
- 型注釈の必須化
    - エクスポートされる関数や変数には明示的な型注釈が必要
- 各ファイル内の型注釈チェック
    - isolatedDeclarations オプションでは、各ファイルが独立して型の推論とチェックする
- エラーメッセージの改善
    - 型注釈が不足している場合、具体的なエラーメッセージが表示され、修正方法も提供されます
- 他のオプションとの併用
    - `isolatedDeclarations`オプションは、`declaration`または`composite`フラグと一緒に使用される必要があります

### デコレータのエラー解消回避方法
`（）`でデコレーターを囲むことでエラーを解消できるそう。
```typescript
class D extends DecoratorProvider {
  m() {
    class C {
      @super.decorate // ❌ error
      method1() { }

      @(super.decorate) // ✅ okay
      method2() { }
    }
  }
}
```

### undefinedもはや定義可能な型名ではない

TypeScript　5.5では下記がエラーになるように変更されました。

```typescript
type undefined = any;
```

### 簡略化された参照ディレクティブ宣言出力

## まとめ
次回のアップデート5.6は2024年9月初旬に予定されているようです！

利用したことな機能も多いので全てを理解することは難しかったです…。

:::note
アップデート内容を見ても全てを完全に理解するのは難しいと思いますが、どんな内容か理解するために調べると知識が深まるのでオススメです！
:::