編集

TypeScript 5.5

2024年6月20日にTypeScript 5.5がリリースされた。

Announcing TypeScript 5.5 - TypeScript

#型述語の推論

次のコードの value is S が推論されるように。

tsx
function isNumber(value: number | string): value is number {
  return typeof value === "number";
}

特に filter メソッドで便利になる。

tsx
// TypeScript 5.4
const values = [2, null, 3].filter((x) => x !== null);
// => (number | null)[]

const values = [2, null, 3].filter((x): x is number => x !== null);
// => number[]

// TypeScript 5.5
const values = [2, null, 3].filter((x) => x !== null);
// => number[]

また、今までよりも型安全になる。型述語はあくまでユーザー定義であるため、次のような嘘をつくことが出来ていた。

tsx
function isDog(x: Animal): x is Dog {
  return x instanceof Cat;
}

#Control Flow Narrowing for Constant Indexed Accesses

次のようなケースで、正確に型の絞り込みがされるように。

tsx
function f1(obj: Record<string, unknown>, key: string) {
  if (typeof obj[key] === "string") {
    // TypeScript 5.4: obj[key]がunknownとして推論されエラーが出ていた。
    // TypeScript 5.5: obj[key]がstringに絞り込まれる。
    obj[key].toUpperCase();
  }
}

次のようにすれば今までも問題はなかったため、あまり恩恵はないかもしれない。

tsx
function f1(obj: Record<string, unknown>, key: string) {
  const x = obj[key];
  if (typeof x === "string") {
    x.toUpperCase();
  }
}

#The JSDoc @import Tag

次のような記述が出来るようになった。

tsx
/** @import { Linter } from "eslint" */

/** @type { Linter.FlatConfig[] } */
const config = [];
export default config;

今までは次のように記述するのが一般的だった。

tsx
/** @type { import("eslint").Linter.FlatConfig[] } */
const config = [];
export default config;

#正規表現構文チェック

TypeScript が、正規表現の基本的な構文チェックを行うように。これは TypeScript 5.5 では正規表現リテラルに限定されており、new RegExpの場合はチェックされない。

詳しくは、次の記事が参考になる。

TypeScript 5.5 で追加された正規表現構文チェックを理解する

#明示的な型注釈の強制 isolatedDeclarations

isolatedDeclarationsは明示的な型注釈を強制するオプション。これにより、複雑な型推論を削減でき、高速なビルドや型チェックの並列化などの恩恵を受けることが出来る。

このオプションの意義については、TypeScript 5.5 のリリース記事でも詳細に書かれている。

Announcing TypeScript 5.5 - TypeScript

とても有益なオプションに見えるが、安易に有効化するとオーバーエンジニアリングになる可能性があるため、メリットとデメリットを把握した上で導入を検討すべき。小さなライブラリでは効果的な場合が多い。

#Config ファイルのテンプレート変数 ${configDir}

tsconfig.json で次のように記述ができるようになった。

json
{
    "compilerOptions": {
        "typeRoots": [
            "${configDir}/node_modules/@types"
            "${configDir}/custom-types"
        ],
        "outDir": "${configDir}/dist"
    }
}
編集