AltJSとTypeScriptとは
昨今、
TypeScript以外にもさまざまなAltJSがあります。たとえばLL
TypeScriptの開発はC#やTurbo Pascalの開発者として有名なAnders Hejlsberg氏が中心となってMicrosoftで開発されました。
開発の中心はMicrosoftですが、
TypeScriptを今すぐに試してみる
TypeScriptのインストールについてはのちほど解説しますが、
TypeScriptの特徴とメリット
TypeScriptが実際にどのような言語なのか、
TypeScriptのおもな特徴は次のとおりです。
- 静的型付け言語であり、
あいまいさを回避しやすい - ECMAScriptのスーパーセットで、
かつECMA Script 6の機能を先取りしている - 変換しても平易なECMAScriptが出力される
- 既存ライブラリとの相互運用のために外部に型定義ファイルを持てる
TypeScriptの文法
TypeScriptの文法は基本的にJavaScriptの言語部分
function sayHello(message) {
alert(message);
}
sayHello("Konnichiwa!");
このTypeScript のコードを変換すると次のJavaScriptのコードになります。
function sayHello(message) {
alert(message);
}
sayHello("Konnichiwa!");
この2つのコードを比べるとわかりますが、
先ほどの変換例のとおり、
ではJavaScriptのコードをTypeScriptのコードにコピー&ペーストすればそのまま使えるかというと、
TypeScriptは静的型付け言語
TypeScriptの特徴は、
静的型付け言語とは、string
、number
などを宣言しておき、
function sayHello(message : string) {
alert(message);
}
sayHello("Konnichiwa!");
この例では、sayHello
関数は引数として文字列しか受け取れないことを示すため、: string
という宣言を追加しています。たとえば最後のsayHello
関数の呼び出しで引数に数値の1を指定してコンパイルするとstring
型を受け取るはずだけどnumber
型が渡されていて、
var message: string; // string(文字列型)の変数を定義
message = 1;
// ↑ エラー: Cannot convert 'number' to 'string'.
このように実行前のチェックが可能になるのが静的型付け言語のメリットです。静的な型付けをするメリットはのちほどもう少し詳しく紹介します。なお、
大規模開発をサポートする要素
TypeScriptには、
module Sample {
export class Greeter {
message: string;
constructor(message: string) {
this.message = message;
}
sayHelloAfterSecond(): void {
setTimeout(() => alert(this.message), 1000);
}
}
}
new Sample.Greeter('Konnichiwa!!').
sayHelloAfterSecond();
モジュールを利用すると、
静的型付け言語であるメリット
TypeScriptが静的型付け言語であり、
コンパイル時のエラー
先ほど述べたとおり、

これはリファクタリングなどを行う場合にもメリットになります。たとえば特定のクラスのメソッド名を変更した場合、
Visual StudioやWebStormなどのIDEとの相性の良さ
Visual StudioやWebStormといったいわゆるIDE
IDEのサポートで代表的なものと言えばコード補完ではないでしょうか。Visual StudioやWebStormでも、

またコードのエラーをエディタ上に表示する機能もあります。常にコードの状態を確認できるので、

IDEらしい強力な機能としては、

このような機能は静的な型付けをしているおかげで正確に動作できているのです。Visual StudioやWebStormにはJavaScriptのコード補完のサポートもありますが、
ハイライトやリネームの機能はPlaygroundでも実際に体験できますので、
TypeScriptのインストールとコンパイル
Playgroundでコードを書くのは即座に試せてよいのですが、
インストールする
Windowsをお使いの方はVisual Studioを利用するのが簡単でしょう。Visual Studio 2013のバージョンUpdate 2以降にはTypeScriptの開発ツール

またOS XやLinux、sudo
を付けて次のコマンドを実行してください。
% npm install -g typescript
このコマンドを実行してインストールが完了すると、tsc
コマンドを実行できるようになります。
コードを書いてコンパイルする
Visual Studioでは、
Node..ts
)tsc
コマンドの引数として渡せばコンパイルされます。
% tsc script.ts
tsc
コマンドを実行すると、.ts
ファイルと同名の.js
ファイルが生成されます。しかし、tsc
コマンドを実行するのは面倒です。そのため、tsc
コマンドには変更を監視して自動でコンパイルする--watch
オプションが用意されています。
% tsc --watch script.ts
--watchオプションを指定してtscコマンドを実行すると終了せずにそのまま待機状態になり、
TypeScriptの文法
JavaScriptにも型がありますが、
型と変数の宣言
TypeScriptは組み込みで次の型を持っています。
- string:文字列型
- number:数値型
- boolean:ブール値
(true/ false) 型 - void:何もない、
空からを表す型
ほかにも関数やオブジェクト、null
などの型もありますが、
TypeScriptでの変数宣言はJavaScriptと同様var
を使います。宣言の変数名の後ろにコロンと型名を書くと変数の型を指定できます。
var text: string;
var count: number;
var enabled: boolean;
変数の型が指定されている場合、
// 文字列型の変数に数値を代入しようとしてエラー
text = 1;
// 数値型の変数に文字列を代入しようとしてエラー
count = "1";
// ブール型の変数に数値を代入しようとしてエラー
enabled = 0;
しかし、
var text = "hauhau";
var count = 10;
var enabled = true;
一見JavaScriptと同様に見えますね。TypeScriptでは型推論というしくみにより、
// 文字列型の変数として初期値を持たせつつ定義
var text = "hauhau";
// 文字列型の変数に数値を代入しようとしてエラー
text = 1;
これでまったく異なる型の値を間違えて代入することや混在することがなくなります。気軽に記述しながら静的型付け言語の恩恵を受けられるのです。
関数の定義
TypeScriptでの関数の定義は、function
キーワードに続けて関数名を書き、
// 引数aとbはnumber型で、戻り値がstring型
function addAndToString(a: number, b: number): string {
return (a + b).toString();
}
addAndToString('1', '2'); // エラー: パラメータはnumber型しか受け取らない
var value: number = addAndToString(1, 2); // エラー: number型の型にstring型は入ない
JavaScriptには通常の関数定義のほかに匿名関数
document.body.addEventListener('click', function () {
alert('clicked!');
});
TypeScriptでは、
document.body.addEventListener('click', () => {
alert('clicked!');
});
長かったfunction
キーワードがなくなり、=>
が登場しました。function
がなくなったおかげでスッキリしています。
さらに、
[1,2,3].map((v) => { return v * 2; });
[1,2,3].map((v) => v * 2);
ブロックを取る書き方はfunction
を使う定義とほとんど変わりませんが、
[1, 2, 3].map(function (v) {
return v * 2;
});
なお、
[1,2,3].map(v => { return v * 2; });
[1,2,3].map(v => v * 2);
クラスの定義
TypeScriptでクラスを定義するには、
// Greeterクラスを定義
class Greeter {
// string型のプロパティ
message: string;
// パラメータを取るコンストラクタ
constructor(message: string) {
this.message = message;
}
// メソッド
sayHello(): void {
alert('Hello! ' + this.message);
}
}
new Greeter('Konnichiwa').sayHello();
クラスの定義にはプロパティ、function
キーワードは使いません。
定義したクラスを使うにはJavaScriptとまったく同様に、new
でインスタンスを生成して利用します。これはJavaScriptから直接扱えるという意味でもあり、
TypeScriptではメソッドやプロパティにprivate
修飾子を付けて宣言すると、
ほかのクラスベースの言語と同じように、Greeter
クラスを継承したAisatsu
クラスを定義して、sayHello
メソッドを上書きしています。
class Aisatsu extends Greeter {
sayHello(): void {
alert('Konnichiwa! ' + this.message);
}
}
ところでコードを書いていると、
// canvas要素を取ってくる
var canvasE = document.querySelector('canvas');
// Canvas 2D Contextを取得する
var ctx = canvasE.getContext('2d');
このコードはJavaScriptとしては問題なく動作しますが、
まず、document.
はドキュメント内のcanvas
要素を返しますが、querySelector
メソッドの戻り値は要素を表す汎用的なElement
型ですcanvasE
はElement
型です)。この値に対してgetContext
メソッドを呼び出そうとしても、Element
型にはそのようなメソッドはないのでコンパイルエラーになります。
この場合は型のキャストElement
型ではなくgetContext
メソッドを持つ下位のHTMLCanvasElement
型であると認識できればよいのです。キャストするには、<TypeName>
を変数や戻り値の前に置きます。このコードでは、document.
の戻り値をHTMLCanvasElement
型にキャストしています。
// canvas要素を取ってくる
var canvasE = <HTMLCanvasElement>document.querySelector('canvas');
// Canvas 2D Contextを取得する
var ctx = canvasE.getContext('2d'); // ← OK
キャストのエラーは最終的に実行されたときに発生するので注意が必要です。リスト3のコードでは、canvas
要素の実体がまさにHTMLCanvasElement
型なので正常に動作しますが、div
要素など)HTMLCanvasElement
型にキャストすると、
モジュール
TypeScriptにはモジュールと呼ばれるしくみがあります。モジュールには外部モジュールと内部モジュールがありますが、Greeter
というクラスが2つ出てきますが、
module Sample.Module1 {
export class Greeter {
hello(): void { alert('Hello!'); }
}
}
module Sample.Module2 {
export class Greeter {
hello(): void { alert('Konnichiwa!'); }
}
}
new Sample.Module1.Greeter().hello(); // => Hello!
new Sample.Module2.Greeter().hello(); // => Konnichiwa!
モジュールを定義するにはmodule ModuleName {…… }
というブロックでモジュールに含めたいコードを囲みます。デフォルトではモジュール内で定義されたクラスはそのモジュールで閉じていて、class
などの定義の前にexport
修飾子を指定する必要があります。
module Sample.Module3 {
class Greeter {
hello(): void { alert('Hi!'); }
}
}
new Sample.Module3.Greeter().hello();
// => classをexportしていないのでコンパイルエラー
インタフェース
TypeScriptにはインタフェースと呼ばれるしくみがあります。インタフェースは、
たとえば、message
プロパティを持つインタフェースを指定したクラスを定義しています。
interface IGreeting {
message: string;
}
class Hello implements IGreeting {
message = 'Hello!';
}
class Konnichiwa implements IGreeting {
message = 'Konnichiwa!';
}
function say(greeting: IGreeting): void {
alert(greeting.message);
}
say(new Hello()); // => Hello!
say(new Konnichiwa()); // => Konnichiwa!
インタフェースはクラスの宣言の一部として指定でき、class Hello implements IGreeting
という宣言は、Hello
はIGreeting
インタフェースのメソッドを持つ必要がある」Hello
クラスからmessage
プロパティを削除するとコンパイルエラーになります。
代入の互換性
TypeScriptのインタフェースやクラスは、
interface IGreeting {
message: string;
}
function say(greeting: IGreeting): void {
alert(greeting.message);
}
// IGreetingと同じプロパティを持つがIGreetingの実装を明示的に宣言していない
class Hi {
message = 'Hi!';
}
// HiクラスはIGreetingとして扱える
say(new Hi()); // => Hi!
// 匿名オブジェクトはstring型のmessageプロパティがあるのでIGreetingとして扱える
say({ message: 'Ohayo-gojyaimasu!' }); // => Ohayo-gojyaimasu!
一方、message
プロパティの型がstring
ではないのでエラーになり、message
プロパティがないのでエラーになります。
say({ message: 1 });
say({ msg: 'Hoge!' });
その他の機能
TypeScriptには、
- ジェネリクス
- プロパティ
(getter/ setter) - 列挙型
(Enum) - インデクサ
- import対応
機能は多いですが、
外部ライブラリと定義
ここまでTypeScript自体の紹介をしてきましたが、
TypeScriptを利用した開発で使うライブラリは、
そこでTypeScriptには、

しかし、npm
パッケージからtsd
コマンドをインストールすれば簡単に取得/
まとめ
ほんの触り程度の紹介しかできませんでしたが、