Vue.jsもVanilla JSも好きだ。しかしTypeScriptの型システムは羨ましい。

Vue.jsもVanilla JSも好きだ。しかしTypeScriptの型システムは羨ましい。

Vue.jsはTypeScriptと相性が悪いと言われています。 私はVanilla JSが好きなので個人開発用途では大した問題ではないのですが、ことチーム開発においては型システムがないと厳しいものがあります。

型システムと生産性

個人開発であれば型システムがあろうがなかろうが自己流で統一できるので大きな問題にはならないです。

ただチーム開発の場合、複数人の癖が入り混じったコードで品質を確保する必要があります。 IDEが強力にサポートしてくれる型システムは簡単に客観的な評価が得られる手段として重宝します。

型システムのないRubyやJavaScript(node.js)でエコシステムが発達しているのは、型システム以外の方法で生産性を確保する代替手段と捉えることができるのかもしれません。

vanilla_type.js

Vanilla JSに型システムを導入できないものかと実験的なライブラリを作ってみました。

仕組み

簡単に言うと値のチェック関数を生成します。 見た目や使い勝手が型システムっぽくなるようにしています。

関数の先頭でガード節として機能するので、型定義以外でのコード量もほとんど増えないと思います。

コード例

1.型を定義する

例として単一ユーザを表現するUserTypeを定義します。

//ユーザ型
const UserType = VanillaType.ObjectOf({
	age: VanillaType.NumberInRange(0, 100),
	name: VanillaType.String,
	mail: VanillaType.NullableStrMail,
});

2.型が違うとエラーになる

上で作った型に値を通すと、正しい値の場合はそのまま返却し、期待しない値の場合は例外が発生します。

const taro = UserType({ age: 10, name: "taro", mail: "taro@abc.com" });
const jiro = UserType({ age: 11, name: "jiro", mail: null });//nullable
const sabu = UserType({ age: "a", name: "sabu", mail: "sabu@abc.com" });//Uncaught Error: children of object(key: age) was invalid.

3.ガード節に組み込む

関数の入り口でガード節として機能させるとスッキリ書けます。 ガード節ごとに毎回同じチェックロジックを書くよりは生産的になります。

function append_user(_user){
	const user = UserType(_user);//<-[ココ]ガード節で型チェック
    //登録処理…
    Biz.users.append(user);
}

まだ実験的

とりあえず作ってみたらいい感じに書けることに気付いて嬉しいのですが、利用実績といえるアプリケーションもなく真価は不明です。 また、あくまで型システムっぽく動く型チェッカージェネレータなので、IDEのサポートも期待できないので効果は限定的かもしれません。

既知のバグも残っており、もう少し作りこんでいく必要がありますが、ワタシ的には面白くなりそうだと期待しています。

2021/12/21 追記:同名同コンセプトのライブラリがある!

なんと同じ名前で同じコンセプトのライブラリが既にありました。。。

ワタシの vanilla_type.js よりモダンな書き方ですが、使い勝手ではあまり負けてる気がしません。 (負け惜しみ?)


謝辞
画像は Pixabay 様より使わせていただきました。