LoginSignup
6
6

More than 5 years have passed since last update.

Alloy + Typescript でModelを作成する

Last updated at Posted at 2014-04-09

概要

AlloyのModelをTypescriptのClassの形に書き直しました。

ポイント

  • config.columnsをデータ型として使用する。
  • exports.definitionにModelの定義オブジェクトを渡せるようにする。
  • インターフェースを使ってModelの定義方法をチェックする。

javascriptのModel

以下のModelを元にTypescriptへの書き直しを行います。

Todo.js
exports.definition = {
  config: {
    columns: {
      "task": "text",
      "limitTime": "text",
      "done": "integer"
    },
    adapter: {
      type: "sql",
      collection_name: "Todo"
    }
  },
  extendModel: function (Model) {
    _.extend(Model.prototype, {
      // extended functions and properties go here
    });

    return Model;
  },
  extendCollection: function (Collection) {
    _.extend(Collection.prototype, {
      // extended functions and properties go here
    });

    return Collection;
  }
};

TypescriptのModel

以下の形になりました。

Todo.ts
/// <reference path="IExportableModel.d.ts"/>
module models {
    export class Todo extends Backbone.Model implements IExportableModel {
        public config = Todo.config;
        public exportsDefinition = Todo.exportsDefinition
        static config = {
            columns: { 
                "task": "text",
                "limitTime": "numeric",
                "done": "text"
            },
            adapter: {
                type: "sql",
                collection_name: "Todo"
            }
        };
        static exportsDefinition = {
            config: Todo.config,
            extendModel: function(Model: Backbone.Model) {
                _.extend(Model.prototype, Todo.prototype);
                return Model;
            },
            extendCollection: function(Collection: Backbone.Collection) {
                _.extend(Collection.prototype, {
                    // extended functions and properties go here
                });
                return Collection;
            }
        };

        constructor(attributes?: any, options?: any) { 
            super(attributes, options);
        }

        public toJSON(options?: any): typeof Todo.config.columns {
            return super.toJSON(options);
        }
    }
}

declare var exports: { definition: any };
exports.definition = models.Todo.exportsDefinition;

詳細

config.columnsをデータ型として使用する

Typescriptの型推論はオブジェクトリテラルの内部構造もちゃんとデータ型として推論してくれます。
この機能を利用して、toJSONメソッド戻り値のデータ型を設定したオーバーライドメソッドを作成します。

Todo.ts
    public toJSON(options?: any): typeof Todo.config.columns {
        return super.toJSON(options);
    }

これで、toJSONメソッドの戻り値のオブジェクトからフィールド名が入力補完できるようになります。

exports.definitionにModelの定義オブジェクトを渡せるようにする

static変数 exportsDefinition を定義し、exports.definition に渡します。

Todo.ts
declare var exports: { definition: any };
exports.definition = models.Todo.exportsDefinition;

クラスに定義したメソッドはprototypeプロパティに格納されるので、exportsDefinitionのexportModelの定義を以下のようにすることで、クラスのメソッドをexportsDefinitionに含めることができます。

Todo.ts
extendModel: function(Model: Backbone.Model) {
    _.extend(Model.prototype, Todo.prototype);
    return Model;
}

インターフェースを使ってModelの定義方法をチェックする

他のModelクラスを作成するときにも同様の方法でexportsDefinitionが定義されることを保証するために、インターフェースを作成します。

IExportableModel.ts
interface IExportableModel {
    config: {
        columns: any;
        adapter: {
            type: any;
            collection_name: any
        }
    };

    exportsDefinition: {
        config: typeof config;
        extendModel: (Model: Backbone.Model) => Backbone.Model;
        extendCollection: (Collection: Backbone.Collection) => Backbone.Collection;
    };
}

追記

誤解があると申し訳ないので追記です。
私はTitanium + Alloy も TypeScript も先月初めて触った初心者です。
新しい環境と言語で試行錯誤しながらやってみたことを綴っています。
なるべく有用な情報を共有したいと思ってはいますが、ちょっとした間違いから根本的に間違っていることまで色々間違いがあるかもしれません。どうぞご容赦ください。

6
6
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
6
6