TypeScriptバージョン3から5.2までのアップデート内容まとめ ──型の絞り込みについて解説
ますます便利になるTypeScript! バージョン3からの変更点と総まとめ 第4回
アサーション関数
ここまで、制御フロー分析に伴う型の絞り込みを紹介してきました。次に、制御フロー分析とは別の型の絞り込みを紹介します。それは、アサーション関数です。
例外発生関数の利用
例えば、リスト6の(1)のreturnJSON.result.msgが存在しない場合にエラーを発生させる関数として、リスト12のassertResultMsgIsString()を用意したとします。その上で、extractResult()関数をリスト12のように書き換えたとします。
function assertResultMsgIsString(result: unknown) {
if(result == null || typeof result != "object" || !("msg" in result) || typeof result.msg != "string") { // (1)
throw Error(); // (2)
}
}
function extractResult(returnJSON: ReturnJSON): string {
let result = "通信失敗";
if(returnJSON.status == 1) {
let result = "データ取得失敗";
assertResultMsgIsString(returnJSON.result); // (3)
result = returnJSON.result.msg; // (4)
}
return result;
}
リスト12の(1)はリスト6の(1)のifの内容を反転させた内容となっており、この場合、引数のresultにはmsgは存在しないとして、(2)でエラーを発生させています。そして、extractResult()関数内では、このassertResultMsgIsString()関数を(3)で実行して、msgが存在するかどうかの判定として利用しています。つまり、制御フロー分析の代わりとして利用しています。
しかし、ここで問題となるのは(4)です。(3)でエラーが発生しなかったということは、(4)の段階でreturnJSON.result.msgは存在するはずです。すなわち、ここで型の絞り込みが行われければならないはずです。しかし、TypeScriptのコンパイラはこのことを認識できず、図6のエラーとなってしまいます。
asserts構文
この問題を解決するためにバージョン3.7で導入されたのがassertsキーワードを利用したアサーション関数です。リスト12のassertResultMsgIsString()関数の戻り値の型として、リスト13の(2)の記述をするだけで、図6のエラーは表示されなくなります。この(2)の意味するところは、関数からエラーが発生しなければ、引数であるresultは(1)のResultObj型であることを保証する、という意味です。これにより、型の絞り込みが働くようになります。
interface ResultObj { // (1)
msg: string;
}
function assertResultMsgIsString(result: unknown): asserts result is ResultObj { // (2)
:
}
satisfies演算子
最後に紹介するのは、satisfies演算子です。
ユニオン型の問題
例えば、リスト14の(1)のようなReturnJSON型を考えます。このReturnJSON型は、各プロパティがユニオン型で定義されています。そして、そのReturnJSON型のオブジェクトリテラルとして、(2)のrJsonを定義し、(3)でそのプロパティresultのErrorオブジェクト内のプロパティmessageにアクセスしています。
interface ReturnJSON { // (1)
status: 0 | 1;
result: string | Error;
}
const rJson: ReturnJSON = { // (2)
status: 0,
result: new Error("ダメでした")
};
const error = rJson.result.message; // (3)
このコードは一見、問題ないように思えますが、実は、(3)で図7のエラーとなります。これは、エラーメッセージの通り、resultがstringとErrorのユニオン型であるために起こるエラーです。
satisfiesによる型指定
この問題を解決するためにバージョン4.9で導入されたのがsatisfies演算子による型指定です。リスト14の(2)のrJsonをリスト15のように定義すると、(3)のエラーは解消されます。
const rJson = {
status: 0,
result: new Error("ダメでした")
} satisfies ReturnJSON;
このsatisfiesによる型指定を行うことで、リスト14の(2)の型指定とは違い、rJsonの構成要素が優先され、resultがErrorオブジェクトとして扱われる一方で、例えば、othersのようなReturnJSONに定義されていないプロパティをrJsonに定義しようとすると、エラーとなります。これは、satisfiesによる型指定では、オブジェクトのプロパティ構成がReturnJSONに一致するように緩く判定されるからです。
まとめ
TypeScriptのバージョン5.2までに導入された新機能をテーマごとに紹介する本連載の第4回目はいかがでしたでしょうか。
今回は、型の絞り込みに関するアップデートを紹介しました。次回は、クラス構文に関する新しい仕組みを紹介します。
この記事は参考になりましたか?
既に会員の方はを行ってください。
- ますます便利になるTypeScript! バージョン3からの変更点と総まとめ連載記事一覧
-
- TypeScriptに導入された新たな仕組みのデコレータ、その使い方と利便性とは?
- プライベート構文やアクセサなど、TypeScriptのクラス構文に関する変更点を解説
- TypeScriptバージョン3から5.2までのアップデート内容まとめ ──型の絞り込みに...
- この記事の著者
-
WINGSプロジェクト 齊藤 新三(サイトウ シンゾウ)
<WINGSプロジェクトについて>有限会社 WINGSプロジェクトが運営する、テクニカル執筆コミュニティ(代表 山田祥寛)。主にWeb開発分野の書籍/記事執筆、翻訳、講演等を幅広く手がける。 2026年時点での登録メンバは約50名で、現在も執筆メンバを募集中。興味のある方は、どしどし応募頂きたい。著書、記事多数。 RSS X: @WingsPro_info(公式)、@WingsPro_info/wings(メンバーリスト) Facebook <個人紹介>WINGSプロジェクト所属のテクニカルライター。Web系製作会社のシステム部門、SI会社を経てフリーランスとして独立。屋号はSarva(サルヴァ)。HAL大阪の非常勤講師を兼務。
※プロフィールは、執筆時点、または直近の記事の寄稿時点での内容です
-
山田 祥寛(ヤマダ ヨシヒロ)
静岡県榛原町生まれ。一橋大学経済学部卒業後、NECにてシステム企画業務に携わるが、2003年4月に念願かなってフリーライターに転身。Microsoft MVP for Visual Studio and Development Technologies。執筆コミュニティ「WINGSプロジェクト」代表。主な著書に「独習シリーズ(Java・C#・Python・PHP・Ruby・JSP&サーブレットなど)」「速習シリーズ(ASP.NET Core・Vue.js・React・TypeScript・ECMAScript、Laravelなど)」「改訂3版JavaScript本格入門」「これからはじめるLaravel実践入門」「はじめてのAndroidアプリ開発 Kotlin編 」他、著書多数。
※プロフィールは、執筆時点、または直近の記事の寄稿時点での内容です
この記事は参考になりましたか?
この記事をシェア
