この度、既存のBackbone.js環境をTypescriptに移行したので注意点などをご紹介します。
型定義はDefinitelyTypedから取得して使っています。
Model
最大の問題は、Modelのgetメソッドの戻り値がany型になってしまうという点です。
このままだと型のメリットが全く受けられません。
そのため、getを使うのをやめてattributesの値を直接見るのが良いです。
内部的にはgetメソッドはattributesの値を返しているだけなので問題ないです。
まず以下のような抽象クラスを定義します
abstract class TypedModel<Props> extends Backbone.Model {
public attributs: Props
}
これで、attributesの型がGenericsのProps型になりました。
後はこのTypedModelを継承してモデルを作ればオッケーです。
interface IUser {
id: number;
name: string;
}
class User extends TypedModel<IUser> {
}
View
DefinitelyTypedにホストされている型定義を使っている場合、コンストラクタのシグネチャが決まっているので、追加のパラメータを渡したい場合はoverrideしてやる必要があります。
この際、constructorとinitializeの両方をoverrideしてやる点が注意です。
interface Options extends Backbone.ViewOptions<User> {
foo: string;
}
class UserView extends Backbone.View<User> {
private foo: string;
// constructorとinitializeの両方にOptionsインターフェースを渡してあげる必要がある
constructor(options: Options) {
super(options)
}
initialize(options: Options) {
this.foo = options.foo
}
}
Router
Viewと同様に、独自のパラメータを渡す場合はconstructorとinitialize両方をoverrideする点だけ注意です。
interface Options extends Backbone.RouterOptions {
bar: string;
}
class AppRouter extends Backbone.Router {
private bar: string;
constructor(options: Options) {
super(options)
}
initialize(options: Options) {
this.bar = options.bar;
}
}
終わりに
既にES2015環境が導入済みであれば、JSからの移行もそんなに大変ではないのでぜひやってみると良いと思います。
それなりに規模のあるアプリ(Viewが100近くあるくらい)でしたが1週間程度で移行を完了することが出来ました。
Reactなど別のフレームワークに移行するのと比べれば遥かに低コストで型の安心感が得られるのでおすすめです。