25
21

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?

More than 5 years have passed since last update.

型定義ベースのアサーションライブラリ types-assert を書いた

Last updated at Posted at 2016-08-23

TypeScriptの型定義ファイル(interface)を活用した、型アサーションライブラリです。

types-assert

使い方

$ npm i types-assert -D

TypeScriptの型定義ファイルを用意する。

type.ts
interface Interface1 {
  stringProp: string;
  numProp: number;
}

in node.js

使うのは、compile()assert()のみ。compile()でtsファイルをロードし、assert()で型チェックする。

app.js
const compile = require('types-assert/compiler').compile;
const assert = require('types-assert/assert').assert;

// tsファイルをtypes-assertのオブジェクトに変換
const type = compile('type.ts');

const obj1 = {
  stringProp: "hoge",
  numProp: 2
};

// 型が正しい場合はスルー
assert(obj1, type.Interface1);

const obj2 = {
  stringProp: "hoge",
  numProp: "2"
};

// 型がおかしいのでError
assert(obj2, type.Interface1);

in browser

Webpack用のtypes-assert-loaderを作った。

$ npm i types-assert-loader -D

Webpackにloaderを定義。

webpack.conf.js
{
  module: {
    loaders: [
      {
        test: /\.ts$/,
        loader: 'types-assert-loader'
      }
    ]
  }
};

.tsファイルをimportすると、Loaderがコンパイルしたオブジェクトを返してくれるので、それでassertする。

index.js
import { assert } from 'types-assert/assert';

import { Interface1 } from './type.ts';

console.log(Interface1);

const obj1 = {
  stringProp: "hoge",
  numProp: "2"
};

// Error!
assert(obj1, Interface1);

何故作ったか

もちろんテスト用のアサーションとしても使えるけど、どちらかというと開発用途を想定している。プロダクションのときはunassertとかで削れるはず。たぶん。

TypeScript好きだけど、辛い

TypeScriptは良い。Objectの型定義を作っておけば、REST APIのレスポンスや、ORMから返ってくるオブジェクトの使いが楽になる。

でも、全てをTypeScriptで書くのは辛い。例えば、バックエンドはnode.jsでTypeScriptを使っているけど、フロントはプレーンなJS、ということがある(コードのライフサイクルや色々な問題で)。そうなると、バックエンド用に作った型定義ファイルがもったいない。

なので、assertという関数ひとつでObjectを再帰的に型チェックできたら良いなと思って作った。

プレーンなObjectを使うことが増えた

Redux(flux)の流行もあり、フロントエンドで標準の型(string、Object、...)だけで構成されたObjectを使う機会が増えた。気がする。

でもReactのpropTypeは嫌い。

なので、assertという関数ひとつでObjectを再帰的に型チェックできたら良いなと思って作った。

TypeScriptの型定義を使う理由

既存のプラットフォームに乗っかる方が楽。また、仮にTypeScriptを使わなくても、型定義ファイルは仕様書としての役割も果たすので、作っておいて損はない。

ただ、今回はTypeScript用に作ったけど、別にコンパイル元のファイルは言語を問わない。JavaやGoのInterfaceからでも(ASTがあれば)同じことは実現できるはず。

まとめ

ふと思いついて作ってみたものなので、どれだけ実用的かはこれから。
あと、コードは適当だしサポートしてない部分もある。Arrayのgenericsも、独自型(interface)の定義もできていない(サポートするかは置いといて)。

誰かが使ってくれるようなら直していく。

25
21
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
25
21

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?