LoginSignup
35
15

More than 5 years have passed since last update.

TypeScriptでランタイム型チェックを行う「io-ts」の軽い紹介

Posted at

TypeScriptのランタイム型チェック

TypeScriptにはランタイム型チェック機能がありません。
次のようなコードも正常にコンパイルされエラーが発生することなく動作します。

const x: string = JSON.parse("1");

これはパフォーマンスなどとのトレードオフなので仕方ないのですが、部分的に動的な型チェックをしたいときもあります。
このような時の解決策としてio-tsを紹介します。

io-tsのメリット

JSON Schemaなどは型とスキーマを2つ書く必要があり大変です。
また大変なだけでなく型とスキーマが異なるといったバグを型システムでチェックすることが出来ません。
コードジェネレーターを使うことで解決できますが、TypeScript上で完結しないのでめんどくさいです。
このような問題はio-tsを使うことで解決します。
ただし再帰型については型推論の関係で型とスキーマを2回書く必要がありますが、型チェックでスキーマと型が違っていればコンパイルエラーが発生します。

基本的な使い方

import * as t from "io-ts";

const hoge = t.type({
  tag: t.literal("Hoge"),
  x: t.string,
  y: t.union([t.number, t.null]),
});

type Hoge = t.TypeOf<typeof hoge>;
/*
type Hoge = {
  tag: "Hoge",
  x: string,
  y: number | null,
};
*/

hoge.is(JSON.parse(str));

もっと詳しい使い方はio-tsのREADMEを見ればすぐ分かるのでこっちを見て下さい。
https://github.com/gcanti/io-ts

どうやって実現しているのか

※ここから先はライブラリを使う分にはあまり知らなくていい情報です。

TSはデコレーターという例外を除いて、型情報から値を生成することは出来ません。
しかし、typeofを使うことで値から型を生成することは出来ます。
そこでスキーマ情報をなるべく具象型で(例えば単にSchemeのような型ではなくSchemeの構造を完全に持っている型)持つように型推論を制御して、typeofで値から型を作ることでこのような事が可能になります。
ちなみにTS3.4でas constが入ったので今までより具象型で持つのが楽になりました。
これはio-tsに限らずTSを使う時に知っておくと役に立つ考え方です。

ちなみに作者のgcanti氏はfp-tsの作者でもあり、他にもTSの型システムを最大限活用したライブラリを多数公開しているので見てみると面白いかもしれません。

35
15
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
35
15