TypeScript の Interface が mofmof.js にもほしい
TypeScript を知ってる前提で書きますよー
(ε・◇・)з TypeScript いいですねー、JavaScriptの上位互換でES6と衝突しない感じでステキですねー。
(ε・◇・)з Interface とかもいいですねー。とりいれたいですねー
Interface を mofmof.js に実装してみました
// TypeScript Style interface Point { x: number; y: number; }
// mofmof.js Style mm.Interface("Point", { x: "number", y: "number" });
(ε・◇・)з モニターから3メートルぐらい離れてみれば、ほぼ同じだね!
実行してみました
以下のコードを実行すると、mm.allow({ x: 1 }, "Point"); の行でアサーションが発生し、ブラウザのコンソールに以下の情報を表示します。
- testInterface 関数内でエラーが発生した
- interface Point に合致していない変数が渡された
- interface Point の詳細はこれ
http://mofmof-js.googlecode.com/svn/trunk/test/mm.js.htm とかで実行できます。
function testInterface() { mm.Interface("Point", { x: "number", y: "number" }); mm.allow({ x: 1, y: 2, z: 3 }, "Point"); // ok mm.allow({ x: 1, y: 2 }, "Point"); // ok mm.allow({ x: 1 }, "Point"); // -> assert } testInterface();
[2012-10-05T07:42:34.067Z]:TypeError: >>> testInterface in mm.allow({"x":1}, Point) interface Point { "x": "number", "y": "number" } at Function.mm_allow [as allow] (js_src/mm.js:1234:23) at js_src/aa.htm:58:8 mm.js:1383 Uncaught TypeError: ASSERTION
(ε・◇・)з o O ( mofmof.js は js生成言語と違って静的解析がないので
(ε・◇・)з o O ( このように全部動的にチェックする感じになりますねー
追記
TypeScript には「変数が複数の型を取る場合にAny型になってしまい型チェックの恩恵を受けられない」という問題があるようです。
TypeScript はコンパイルしてしまうと型情報が落ちるようなので、Any型の変数をチェックするのはユーザの責務になります。
mofmof.js では、"number/string" のようにスラッシュで区切り、複数の型や インターフェース名, クラス名 を指定できます。
// mofmof.js style mm.Interface("Scale", { width: "number/string", height: "Number/String" });
// TypeScript style interface Scale { width: any; height: any; }
// インターフェース定義に、他のインターフェースを指定する事もできます。 mm.Interface("Matrix2D", { scale: "Scale", // Scale Interface を制約として与える m11: "number", m33: "number" }); mm.Interface("TextColor", { setTextColor: "function", getTextColor: "function" }); // クラス定義時に Interface による制約を加えられます。 mm.Class("Canvas:Matrix2D:TextColor", { // Canvas implements Matrix2D, TextColor m11: 0, m33: 0, scale: { width: 0, height: 0 }, init: function() {}, setTextColor: function(color) {}, getTextColor: function() {} }); mm.Class("Canvas3D:Canvas", { // Canvas3D extends Canvas init: function() {} });
mofmof.js の型一覧
mm.allow は mm.allow(mix, "string/number/undefined") のように使う assert 用の関数です。実行時に動的に型をチェックします。
以下は、mm.allow, mm.Interface に指定可能な型の一覧です。*1
- "undefined", "null", "node", "global"
- "string", "number", "boolean", "array", "regexp", "date", "object", "function"
- "list" (NodeList, HTMLCollection, Arguments)
- "attr" (NamedNodeMap)
- "style" (CSSStyleDeclaration)
- mm.Class で定義したクラス名
- mm.Interface で定義したインターフェース名
- function Hoge(){}; new Hoge; で生成した野良クラス名
型名の取得は mm.type(mix) で行います。
むむむ
メソッドの引数と戻り値の型を Interface で定義できたら良いのですが。
このクラスの Interface を
mm.Class("Canvas:TextColor", { setTextColor: function(color) {}, getTextColor: function() {} });
こう定義できたらいいですね。
// 今はこう mm.Interface("TextColor", { setTextColor: "function", getTextColor: "function" });
// できたらこんな感じに mm.Interface("TextColor", { setTextColor: "function(color:Color)", getTextColor: "function():Color" });
*1:クラス名とインターフェース名は大小文字を区別します