<?xml version="1.0" encoding="UTF-8"?><rss version="2.0"
	xmlns:content="http://purl.org/rss/1.0/modules/content/"
	xmlns:wfw="http://wellformedweb.org/CommentAPI/"
	xmlns:dc="http://purl.org/dc/elements/1.1/"
	xmlns:atom="http://www.w3.org/2005/Atom"
	xmlns:sy="http://purl.org/rss/1.0/modules/syndication/"
	xmlns:slash="http://purl.org/rss/1.0/modules/slash/"
	xmlns:series="http://organizeseries.com/"
	>

<channel>
	<title>TypeScriptではじめる、モダンWebアプリケーション開発 &#8211; HTML5Experts.jp</title>
	<atom:link href="/series/typescript-dev/feed/" rel="self" type="application/rss+xml" />
	<link>https://html5experts.jp</link>
	<description>日本に、もっとエキスパートを。</description>
	<lastBuildDate>Sat, 07 Jul 2018 03:14:05 +0000</lastBuildDate>
	<language>ja</language>
	<sy:updatePeriod>hourly</sy:updatePeriod>
	<sy:updateFrequency>1</sy:updateFrequency>
	<generator>https://wordpress.org/?v=4.7.19</generator>
	<item>
		<title>TypeScriptで既存資産を活かしたモダンWeb開発を実践！</title>
		<link>/_iwate/11093/</link>
		<pubDate>Fri, 10 Oct 2014 03:00:48 +0000</pubDate>
		<dc:creator><![CDATA[谷口慈行]]></dc:creator>
				<category><![CDATA[プログラミング]]></category>
		<category><![CDATA[TypeScript]]></category>

		<guid isPermaLink="false">/?p=11093</guid>
		<description><![CDATA[連載： TypeScriptではじめる、モダンWebアプリケーション開発 (4)モダンなWebアプリケーションでは、JavaScriptコードの量は日に日に増しています。多くのコードが必要になる中で、それらすべてを一つの...]]></description>
				<content:encoded><![CDATA[<div class="seriesmeta">連載： <a href="https://html5experts.jp/series/typescript-dev/" class="series-171" title="TypeScriptではじめる、モダンWebアプリケーション開発" data-wpel-link="internal">TypeScriptではじめる、モダンWebアプリケーション開発</a> (4)</div><p>モダンなWebアプリケーションでは、JavaScriptコードの量は日に日に増しています。多くのコードが必要になる中で、それらすべてを一つのファイル内で開発することは不可能といってよいでしょう。</p>

<p>そこでTypeScriptを利用すれば、ファイルが分かれている状態でも型が解決できるようになっており、モジュールごとにファイルを分割した開発が可能になります。加えて、型定義ファイルを用意することで、既存のJavaScriptライブラリを改変することなく、そのまま利用することができます。</p>

<p>今回は、Modules/AsynchronousDefinition（AMD）、または、CommonJSの仕様に準拠したモジュール機構や、既存のJavaScriptライブラリの利用方法について紹介します。</p>

<h2>環境構築</h2>

<p><a href="https://html5experts.jp/_iwate/7114/" target="_blank" data-wpel-link="external" rel="follow external noopener noreferrer">連載第1回</a>で紹介したSublimeText3用のプラグインは、現在のところ、ファイルを超えたインテリセンスなどの支援をサポートしていません。ですが開発版では利用できるため、プラグインをプロジェクトをdevブランチに切り替えます。</p>

<p>Sublime Textを開き、ツールバーから「Preferences」の「Browse Packages…」を選択します。開いたフォルダ内のT3Sフォルダをターミナルで開きます。</p>

<p>第1回目のインストール時にはGitを利用して導入しているので、ただブランチを切り替えるだけでプラグインの更新は完了です。</p>

<p><pre class="crayon-plain-tag">$ git checkout dev</pre></p>

<p>次に、プロジェクトフォルダを作成します。SublimeTextは、任意のフォルダをプロジェクトとして開くことができます。ツールバーから「File」の「Open Folder…」を選択し、プロジェクトにするフォルダを開きます。この解説では、&#8221;ts_project&#8221;フォルダを新規作成したものとします。</p>

<p>そして、プロジェクトフォルダ直下に&#8221;.sublimets&#8221;ファイルを新規作成します。この設定ファイルにプロジェクトの設定を記述します。今回は次のように設定します。</p>

<p></p><pre class="crayon-plain-tag">{
    "root": "app.ts", 
    "settings": {
        "activate_build_system":true,
        "auto_complete":true,
        "node_path":"none",
        "error_on_save_only":false,
        "build_on_save":true,
        "show_build_file":true,
        "build_parameters":{
            "pre_processing_commands":[],
            "post_processing_commands":[],
            "output_dir_path":"./build",
            "concatenate_and_emit_output_file_path":"none",
            "source_files_root_path":"none",
            "map_files_root_path":"none",
            "module_kind":"amd",
            "allow_bool_synonym":false,
            "allow_import_module_synonym":false,
            "generate_declaration":false,
            "no_implicit_any_warning":true,
            "skip_resolution_and_preprocessing":false,
            "remove_comments_from_output":false,
            "generate_source_map":true,
            "ecmascript_target":"ES5"
        }
    }
}</pre><p></p>

<h2>外部モジュール</h2>

<p><a href="https://html5experts.jp/_iwate/9222/" target="_target" data-wpel-link="external" rel="follow external noopener noreferrer">前回（第三回）</a>では、名前空間を構成する内部モジュールを紹介しました。TypeScriptでは、この内部モジュールとは異なり、外部モジュールと呼ばれるモジュール機構があります。外部モジュールでは、プログラムをファイル単位でモジュール化することができ、ビルドオプションによって、AMD、または、CommonJSの仕様に準拠したJavaScriptコードを生成することができます。</p>

<p>前回のおさらいですが、内部モジュールは、 <pre class="crayon-plain-tag">module</pre> キーワードと<pre class="crayon-plain-tag">export</pre>キーワードを使用します。モジュール内がカプセル化され、export指定されたものだけが外部から参照できます。</p>

<p></p><pre class="crayon-plain-tag">module Sample{
	export Class Class1{}
	class Class2{} 
}
var class1 = new Sample.Class1();
var class2 = new Sample.Class2();  // error</pre><p></p>

<p>外部モジュールでは、TypeScriptファイル自体がモジュール化され、他のTypeScriptファイルからインポートすることができるようになります。外部モジュールを記述するには、トップレベルにexportキーワードを付け、インポートには <pre class="crayon-plain-tag">import - require</pre> 文を利用します。外部モジュールのコンパイルには、<pre class="crayon-plain-tag">module</pre>ビルドオプションの設定が必須のため、&#8221;.sublimets&#8221;ファイルの<pre class="crayon-plain-tag">settings.build_parameters.module_kind</pre>が<pre class="crayon-plain-tag">amd</pre>または<pre class="crayon-plain-tag">commonjs</pre>のどちらかになっていることを確認します。</p>

<p></p><pre class="crayon-plain-tag">export class Class1();
class Class2();</pre><p> 
</p><pre class="crayon-plain-tag">import Sample = require("classes")
var class1 = new Sample.Class1();
var class2 = new Sample.Class2(); // error</pre><p></p>

<p><pre class="crayon-plain-tag">require</pre>に拡張子を除いたファイルパスを渡すことで、外部モジュールをインポートすることができます。内部モジュールと同様に、export指定されていないオブジェクトは参照するできません。また、外部モジュールと内部モジュールは併用できます。</p>

<p></p><pre class="crayon-plain-tag">export module A{
	export class Class1{}
	class Class2{}
}
export module B {
	export class Class3{}
}</pre><p>
</p><pre class="crayon-plain-tag">import modules = require("modules");
var class1 = new Modules.A.Class1();
var class3 = new Modules.B.Class3();</pre><p></p>

<p>内部モジュールを利用し、名前空間を切りつつ、外部モジュールを利用して、コンポーネント化することができます。
外部モジュールのコードをコンパイルすると、require文が出力されますが、前述のとおりビルドオプションを設定することで、AMDまたはCommonJSのどちらかに出力することが可能です。フロントエンドで使用する場合はAMD形式に出力し、require.jsを利用してロードします。</p>

<h2>リファレンスパス</h2>

<p>require.jsを使わず、ただ、HTMLにscriptタグを連ねてファイル分けを行う場合には、リファレンスパスを利用します。リファレンスパスはコメント文を利用しており、 <pre class="crayon-plain-tag">/// &lt;reference path="sample.ts"/&gt;</pre> によって記述します。</p>

<p></p><pre class="crayon-plain-tag">...
&lt;script src="sample.js"&gt;&lt;/script&gt;
&lt;script src="app.js"&gt;&lt;/script&gt;
...</pre><p></p>

<p></p><pre class="crayon-plain-tag">module Sample {
	export class Class1{}
}</pre><p></p>

<p></p><pre class="crayon-plain-tag">/// &lt;reference path="sample.ts"/&gt;
var class1 = new Sample.Class1();</pre><p></p>

<h2>型定義ファイル</h2>

<p>先のリファレンスパスを利用することで、既存のJavaScriptライブラリを利用することができます。
TypeScriptでは、<pre class="crayon-plain-tag">declare</pre>キーワードを用いて、すでにあるオブジェクトに対して、型付けを行うことができます。これをアンビエント宣言と呼びます。アンビエント宣言を行うことで、既存のJSライブラリのクラスやオブジェクトに型付けを行い、TypeScriptから参照できるようになります。</p>

<p>アンビエントは、型の定義のみで実装を持ちません。そのため、インターフェースはすでにアンビエントです。インターフェース以外の変数やクラスは<pre class="crayon-plain-tag">declare</pre>キーワードを先頭につけ、インターフェースと同様に実装を記述しないように型のみを定義することでアンビエントを定義できます。</p>

<p>アンビエント宣言は別ファイルに分離し、拡張子を<pre class="crayon-plain-tag">.d.ts</pre>とした型定義ファイルファイルを作成することが慣習的になっています。
例えば、次のような既存JSファイルmylib.jsがあるとします。これをapp.tsで利用するには、型定義ファイルを作成し、リファレンスパスによって参照します。</p>

<p></p><pre class="crayon-plain-tag">var MyLib = {
    version: "1.0.0"
    , message: "Hello"
    , output: function () {
        console.log(this.message);
    }
}</pre><p></p>

<p></p><pre class="crayon-plain-tag">declare var MyLib: {
    version: string;
    message: string;
    output: ()=&gt;void;
};</pre><p></p>

<p></p><pre class="crayon-plain-tag">/// &lt;reference path="mylib.d.ts"/&gt;
MyLib.output();</pre><p></p>

<p>このように、型定義ファイルを用意することで既存のJSライブラリに手を加えず、そのままTypeScriptで利用できます。また、jQUeryなどの人気のあるJavaScriptライブラリの型定義ファイルは<a href="http://definitelytyped.org/tsd/" data-wpel-link="external" target="_blank" rel="follow external noopener noreferrer">TSD(TypeScript Definition manager)</a>を使用することでダウンロードできます。TSDは、型定義ファイルのリポジトリ、<a href="http://definitelytyped.org/" data-wpel-link="external" target="_blank" rel="follow external noopener noreferrer">DefinitelyTyped</a>のマネージャでDefinitelyTypedに集まっている多くの型定義ファイルを管理できます。</p>

<p>TSDはNPMからインストールします。</p>

<p><pre class="crayon-plain-tag">$ npm install -g tsd</pre></p>

<p>このTSDを用いて、jQueryの型定義ファイルをダウンロードしてみます。</p>

<p><pre class="crayon-plain-tag">$ tsd query jquery --action install</pre></p>

<p>ダウンロードした型定義ファイルをリファレンスパスで参照することで、jqueryを利用するコードをTypeScriptで記述することができます。</p>

<p>また、<pre class="crayon-plain-tag">declaration</pre> コンパイルオプションを指定することによってコンパイル時にTypeScriptファイルから型定義ファイルを自動生成できます。あくまで、生成できるのはTypeScriptからでJavaScriptをそのまま変換することはできないので注意が必要です。</p>

<h2>まとめ</h2>

<p>全４回でTypeScriptを紹介してきました。第1回目で述べた通り、TypeScriptは次の特徴を持った言語です。</p>

<ul>
<li>JavaScriptのコードそのまま解釈でき、既存コードから開発をスタートできる。</li>
<li>また、クラスやインターフェース、モジュール化などでコンポーネント化がより容易になる。</li>
<li>かつ、型の検査やインテリセンス、リッチデバッグ環境で大規模開発を助けてくれる。</li>
</ul>

<p>繰り返しになりますが、TypeScriptは型注釈を行うことで、型の不一致から発生するバグを実行前に検知し修正することができます。また、クラスや内部モジュールや外部モジュールによって、コンポーネント化が容易になります。</p>

<p>また、TypeScriptはJavaScriptのスーパーセットでもあり、次世代JavaScriptの仕様を先取りしているだけでなく、アンビエント宣言を用いることで既存のJavaScriptライブラリも型注釈して利用できます。開発環境に関しても、この連載ではSublime Text 3を取り上げましたが、Visual StudioやIntelliJ IDEAなどTypeScriptを力強くサポートしてくれるIDEもあります。</p>

<p>ぜひ皆さんも、TypeScriptでモダンなWebアプリケーション開発を体験してみてください！</p>
]]></content:encoded>
		
		<series:name><![CDATA[TypeScriptではじめる、モダンWebアプリケーション開発]]></series:name>
	</item>
		<item>
		<title>Class、Interface、Module-TypeScriptが提供する目玉機能を一挙紹介！</title>
		<link>/_iwate/9222/</link>
		<pubDate>Fri, 08 Aug 2014 00:00:58 +0000</pubDate>
		<dc:creator><![CDATA[谷口慈行]]></dc:creator>
				<category><![CDATA[プログラミング]]></category>
		<category><![CDATA[TypeScript]]></category>

		<guid isPermaLink="false">/?p=9222</guid>
		<description><![CDATA[連載： TypeScriptではじめる、モダンWebアプリケーション開発 (3)クラス・インターフェース・モジュールは大規模な開発を行う際の強力な味方であり、TypeScriptの重要な機能の一つです。連載第3回目となる...]]></description>
				<content:encoded><![CDATA[<div class="seriesmeta">連載： <a href="https://html5experts.jp/series/typescript-dev/" class="series-171" title="TypeScriptではじめる、モダンWebアプリケーション開発" data-wpel-link="internal">TypeScriptではじめる、モダンWebアプリケーション開発</a> (3)</div><p>クラス・インターフェース・モジュールは大規模な開発を行う際の強力な味方であり、TypeScriptの重要な機能の一つです。連載第3回目となる今回は、オブジェクト指向に欠かせないクラスについて紹介します。</p>

<h2>クラス</h2>

<p>JavaScriptはプロトタイプベースの言語であり、静的なクラスではありません。しかし、多くのライブラリにて静的なクラスを再現する機能が実装され、利用されています。TypeScriptでは、静的なクラスが使用でき、多くのクラスベースの言語と同様のノウハウや実装方法を利用できます。</p>

<p>クラスを定義するには、<pre class="crayon-plain-tag">class</pre>キーワードを使用します。</p>

<p></p><pre class="crayon-plain-tag">class Person {
	private name: string;
	constructor(name: string){
		this.name = name;
	}
	introduceOnSelf(): string{
		return "I'm " + this.name + ".";
	}
}
var tom = new Person("Tom");
tom.introduceOnSelf(); // "I'm Tom."</pre><p></p>

<p>アクセサは<pre class="crayon-plain-tag">private</pre>と<pre class="crayon-plain-tag">public</pre>が指定できます。アクセサを表記しない場合は<pre class="crayon-plain-tag">public</pre>として扱われます。アクセサはTypeScript内でのみ有効で、コンパイル時のチェックにのみ使用されるため、<pre class="crayon-plain-tag">private</pre>を指定しても出力されるJavaScriptコードでプライベートが実現されているわけではありません。あくまでも、TypeScript内でのみ適用されるため、出力されるコードがむやみに複雑になることもありません。</p>

<p>コンストラクタは<pre class="crayon-plain-tag">constructor</pre>というメンバ関数内に記述します。また、コンストラクタのパラメータにアクセサを記述することで、プロパティ宣言と代入文を省略することもできます。</p>

<p>先のコードを省略すると次のようにスッキリと記述できます。</p>

<p></p><pre class="crayon-plain-tag">class Person {
	constructor(private name: string){}
	introduce(): string{
		return "I am " + this.name + ".";
	}
}</pre><p></p>

<p>静的なメンバは<pre class="crayon-plain-tag">static</pre>キーワードを使用して定義します。静的なメンバは作成したクラスのメンバとなるため、<pre class="crayon-plain-tag">this</pre>ではアクセスすることはできないので注意しましょう。</p>

<p></p><pre class="crayon-plain-tag">class Some{
	static className = "Some";
}
Some.className;</pre><p></p>

<p>セッターやゲッターも定義することができます。それぞれ、<pre class="crayon-plain-tag">set</pre>,<pre class="crayon-plain-tag">get</pre>と修飾子を付け、メンバ関数と同様に宣言します。セッターのパラメータの型とゲッターの戻り値の型は一致している必要があります。</p>

<p></p><pre class="crayon-plain-tag">class Some {
	private property: string;
	set Property(value: string) {
		this.property = value;
	}
	get Property(): string {
		return this.property;
	}
}</pre><p></p>

<p>ただし、セッター・ゲッターを利用するためにはコンパイルターゲットをECMAScript 5に指定する必要があります。本連載で使用しているSublime TextのT3Sプラグインの設定では<pre class="crayon-plain-tag">ecmascript_target</pre>を<pre class="crayon-plain-tag">ES5</pre>に設定する必要があります。</p>

<p>もちろん、クラスを継承し、拡張したクラスを宣言することもできます。継承には<pre class="crayon-plain-tag">extends</pre>キーワードを使用します。</p>

<p></p><pre class="crayon-plain-tag">class Parent{
	constructor(){}
	method():void;
}
class Child extends Parent{
	constructor(){
		super();
	}
	method():void{
		super.method();
	}
}</pre><p></p>

<p>オーバーライド時に親のメンバ関数を呼ぶ必要がある場合は、<pre class="crayon-plain-tag">super</pre>キーワードを使用し、親クラスのメンバを参照することができます。</p>

<h2>インターフェース</h2>

<p>クラスと同様にインターフェースも利用することができます。TypeScriptでは、インターフェースはクラスへメンバの実装を強制する際に使用されることはもちろんのこと、単に型としても利用されます。</p>

<p>インターフェースの定義には<pre class="crayon-plain-tag">interface</pre>キーワードを使用し、クラスに実装を強制する際には<pre class="crayon-plain-tag">implements</pre>キーワードを使用します。</p>

<p></p><pre class="crayon-plain-tag">interface ISample{
	property: string;
	method(): void;
}
class SampleClass implements ISample{
	property = "property";
	method(): void{
	}
}</pre><p></p>

<p>インターフェース<pre class="crayon-plain-tag">ISample</pre>の実装が強制されていため、<pre class="crayon-plain-tag">ISample</pre>のメンバすべてが実装されていない場合はコンパイルエラーになります。</p>

<p>JavaScriptでは、多くのパラメータをメソッドに渡す際にオブジェクトにパラメータをまとめる手法をよくとります。TypeScriptでは、このような型の定義にインターフェースが頻繁に利用されます。</p>

<p>次のコードの<pre class="crayon-plain-tag">func</pre>関数は多くのパラメータを受け取る関数です。<pre class="crayon-plain-tag">func</pre>関数は、このパラメータを1つのオブジェクトにまとめて、<pre class="crayon-plain-tag">params</pre>として受け取ります。このとき、<pre class="crayon-plain-tag">params</pre>は<pre class="crayon-plain-tag">any</pre>型ではない型を与えるべきであり、この型を作成するために、TypeScriptでは<pre class="crayon-plain-tag">interface</pre>が頻繁に利用されます。次のコードでは<pre class="crayon-plain-tag">ManyParams</pre>インターフェースとなります。</p>

<p></p><pre class="crayon-plain-tag">interface ManyParams{
    param1?: string;
    param2?: number;
    param3?: boolean;
    // ...
    paramn?: string;
}

function func(params: ManyParams): void {
    ...
}

func({
    param1: "param1"
    , param3: true
});</pre><p></p>

<p>jQueryのAjaxを例にとると次のようになり、引数をインターフェースにすることでパラメータのメタ情報を取得できます。</p>

<p></p><pre class="crayon-plain-tag">interface JQueryAjaxSettings {
	url?: string;
	data?: any;
	type?: string;
	// ... more properties;
}
/**
 * jQueryのajaxメソッドはJQueryAjaxSettings型の引数をとる。
 */
$.ajax({
	url: "/api/values"
	, type: "get"
})</pre><p></p>

<p>TypeScriptでは第1回で紹介したとおり、構造的部分型を採用しているため、インターフェース<pre class="crayon-plain-tag">JQueryAjaxSettings</pre>のインスタンスを生成する必要はなく、オブジェクトを利用できます。</p>

<p>また、TypeScriptのインターフェースでは、関数の型も定義することができ、TypeScriptで使用する型全般にユニークな呼称を定義できるものと言えます。</p>

<p></p><pre class="crayon-plain-tag">interface Listener{
	(ev: Event):void;
}
var l: Listener = function (ev: Event){
}</pre><p></p>

<h2>ジェネリック型</h2>

<p>クラスやインターフェースの力を十分に発揮するには、ジェネリック型（総称型）が必要不可欠です。</p>

<p>TypeScriptは静的型付け言語であり、その恩恵を十分に受けるには、極力Any型の利用を避ける必要があります。すると、あらゆる型に対応したクラスとインターフェースを用意するには、おのずとジェネリック型という仕組みを利用する必要があります。</p>

<p>ジェネリック型を利用することで、データ型に依存することなく、構造や振る舞いを記述することができるようになります。</p>

<p>ジェネリック型を利用する際は、<pre class="crayon-plain-tag">&lt;&gt;</pre>を使用し、型を指定します。</p>

<p>次のコードは、ジェネリック型を利用したスタックのコードです。スタックは<pre class="crayon-plain-tag">push</pre>と<pre class="crayon-plain-tag">pop</pre>のメソッドが存在すればスタックであるとすると、<pre class="crayon-plain-tag">IStack</pre>インターフェースのように表現できます。この時、スタックが扱うデータの型をジェネリック型として<pre class="crayon-plain-tag">T</pre>で記述します。
ジェネリック型は型注釈する際にデータ型を指定することができ、<pre class="crayon-plain-tag">string</pre>型のデータを扱うスタックであれば、<pre class="crayon-plain-tag">IStack</pre>と注釈できます。この時、<pre class="crayon-plain-tag">T</pre>は全て<pre class="crayon-plain-tag">string</pre>であると解決されます。</p>

<p><pre class="crayon-plain-tag">push</pre>メソッドのパラメータは<pre class="crayon-plain-tag">T</pre>であるため、このインスタンスでは<pre class="crayon-plain-tag">string</pre>となり、コンパイラにより型がチェックされます。</p>

<p></p><pre class="crayon-plain-tag">interface IStack&lt;T&gt; {
	push(item: T): void;
	pop(): T;
}
var stack: IStack&lt;string&gt; = [];
stack.push("stack"); // ok
stack.push(0); // error</pre><p></p>

<p>また、ジェネリック型にはごく簡単な上限制約を設けることができます。制約に合致しない場合はコンパイルエラーとなります。</p>

<p></p><pre class="crayon-plain-tag">interface IComparable {
    compareTo&lt;T extends IComparable&gt;(item: T): number;
}
function min&lt;T extends IComparable&gt;(a: T, b: T): T {
    return a.compareTo(b) &lt; 0 ? a : b;
}</pre><p></p>

<p><pre class="crayon-plain-tag">a.compareTo(b)</pre>のようにパラメータから型推測をするので、型の明示的な指定をほとんど記述することなく使用できます。</p>

<p>先ほど、ごく簡単な上限制約と紹介したのは、次の<pre class="crayon-plain-tag">&lt;T extends IComparable&gt;</pre>ようにジェネリック型の<pre class="crayon-plain-tag">T</pre>を上限型の宣言に使用できないためです。 多くのジェネリック型を取り入れている言語では使用できるため、つまづきやすいポイントと言えます。</p>

<p></p><pre class="crayon-plain-tag">interface IComparable&lt;T&gt;{
	compareTo(item: T): number;
}
// エラー: Tが上限型のジェネリックに指定されている
function min&lt;T extends IComparable&lt;T&gt;&gt;(a:T, b:T): T{
	return a.compareTo(b) &lt; 0 ? a : b;
}</pre><p></p>

<p>実際は、TypeScriptは制限的部分型であるため、上限制約を定義せずとも、先のようなロジックは利用できるためあまり使用されることはなく、むしろ、制約を設けるよりも制限的部分型を大いに利用するような仕様であるといえます。</p>

<h2>内部モジュール</h2>

<p>TypeScriptには内部モジュールと外部モジュールの2つのモジュール機能があり、プログラムを機能ごとに切り分けることができます。
内部モジュールはこれを利用することで、名前空間を分けることができます。名前空間を分けることでより構造化してアプリケーションを構築できるようになります。
モジュールを利用するには<pre class="crayon-plain-tag">module</pre>キーワードを利用し、次のように記述します。 モジュールを外部スコープから参照可能にする場合は、<pre class="crayon-plain-tag">export</pre>キーワードを使用します。</p>

<p></p><pre class="crayon-plain-tag">module M{
	class Private{}
	export class Public{}
}
new M.Public(); // ok
new M.Private(); // error</pre><p></p>

<p>モジュールはネストすることができます。このとき、ネストされたモジュールを参照可能にするには、やはり<pre class="crayon-plain-tag">export</pre>キーワードを使用します。</p>

<p></p><pre class="crayon-plain-tag">module M{
	export module N{
		export class O{}
	}
}
new M.N.O();</pre><p></p>

<p>先のネストされたモジュールは、次のように<pre class="crayon-plain-tag">.</pre>で区切り、短縮して書くことができます。</p>

<p></p><pre class="crayon-plain-tag">module M.N{
	export class O{}
}
new M.N.O();</pre><p></p>

<p>また、モジュールは分割して記述することができます。</p>

<p></p><pre class="crayon-plain-tag">module M{
	export class A{}
}
module M{
	export class B{}
}
new M.A();
new M.B();</pre><p></p>

<p>モジュールのネストが深くなると、参照する際に記述量が多くなりますが<pre class="crayon-plain-tag">import</pre>キーワードを使用して短い別名をつけ、短縮して使用することができます。</p>

<p></p><pre class="crayon-plain-tag">module Long.NameSpaces{
	export class C{}
}
new Long.NameSpaces.C();
import C = Long.NameSpaces.C;
new C();</pre><p></p>

<h2>まとめ</h2>

<p>TypeScriptでは、他のクラスベースの言語とほとんど差異なく、静的なクラスを使用できます。
また、TypeScriptではインターフェースが非常に広範囲で活躍します。プリミティブな型以外のほとんどの型はインターフェースで表現可能です。JavaScriptコードをTypeScriptに置き換える際には、プログラム内で利用する型をインターフェースで整理してみましょう。</p>

<p>次回は、ファイル分割や外部モジュール、jQueryなどのJavaScriptライブラリを、TypeScriptで使用する方法を紹介します。</p>
]]></content:encoded>
		
		<series:name><![CDATA[TypeScriptではじめる、モダンWebアプリケーション開発]]></series:name>
	</item>
		<item>
		<title>AltJS初心者必見！型注釈と関数にみるTypeScriptの魅力</title>
		<link>/_iwate/7650/</link>
		<pubDate>Fri, 04 Jul 2014 04:00:40 +0000</pubDate>
		<dc:creator><![CDATA[谷口慈行]]></dc:creator>
				<category><![CDATA[プログラミング]]></category>
		<category><![CDATA[TypeScript]]></category>

		<guid isPermaLink="false">/?p=7650</guid>
		<description><![CDATA[連載： TypeScriptではじめる、モダンWebアプリケーション開発 (2)前回はTypeScriptの魅力を3つほど紹介し、TypeScriptの開発環境を構築しました。今回はTypeScriptの基本文法とTyp...]]></description>
				<content:encoded><![CDATA[<div class="seriesmeta">連載： <a href="https://html5experts.jp/series/typescript-dev/" class="series-171" title="TypeScriptではじめる、モダンWebアプリケーション開発" data-wpel-link="internal">TypeScriptではじめる、モダンWebアプリケーション開発</a> (2)</div><p>前回はTypeScriptの魅力を3つほど紹介し、TypeScriptの開発環境を構築しました。今回はTypeScriptの基本文法とTypeScriptの魅力の一つであり、TypeScriptを最も特徴付ける機能である型注釈について紹介します。</p>

<h2>関数</h2>

<p>型注釈の説明に入る前に、TypeScriptの関数について説明します。</p>

<p>前回強調したとおり、「JavaScriptのコードそのまま解釈でき、既存コードから開発をスタートできる」ということは、TypeScriptの特徴の一つです。なので、シンタックスはJavaScriptのコードと大差ありませんが、より使いやすく拡張されているものもあります。特に関数は様々な拡張がなされています。</p>

<p>具体的には次の4つの機能が利用できます。</p>

<ul>
<li>オプショナルパラメータ</li>
<li>デフォルトパラメータ </li>
<li>可変長パラメータ</li>
<li>ラムダ式</li>
</ul>

<h4>オプショナルパラメータ</h4>

<p>JavaScriptでは宣言されているパラメータの数と、実際にコールする際のパラメータの数は違っていても問題はありませんでした。</p>

<p></p><pre class="crayon-plain-tag">function func(arg1, arg2){
}
func();  // なくてもok
func(0); // 足りなくてもok
func(0,1,2); // 多くてもok</pre><p></p>

<p>しかし、TypeScriptは静的型付け言語であり、宣言通りに値を渡さなければコンパイルエラーとなります。</p>

<p></p><pre class="crayon-plain-tag">function func(arg1, arg2){
}
func(0,1); // ok
func();    // コンパイルエラー
func(0);   // コンパイルエラー
func(0,1,2); // コンパイルエラー</pre><p></p>

<p>このため、TypeScriptではJavaScriptと同様にパラメータに値を渡さないことを許容するには、<pre class="crayon-plain-tag">?</pre>を用いて明示的に宣言をする必要があり、これをオプショナルパラメータと呼びます。</p>

<p></p><pre class="crayon-plain-tag">function func(arg1, arg2?){
    if(!!arg2){
    }
}
func(0,1); // ok
func();    // コンパイルエラー
func(0);   // ok
func(0,1,2); // コンパイルエラー</pre><p></p>

<p>オプショナルパラメータは<pre class="crayon-plain-tag">?</pre>をパラメータの後に付け、宣言し、値が渡されたどうかは実装で動的に検査する必要があります。</p>

<h4>デフォルトパラメータ</h4>

<p>さらに、TypeScriptではECMA-262 6th Editionの仕様の一つであるデフォルトパラメータが利用できるため、関数にデフォルトのパラメータを設けることができます。</p>

<p></p><pre class="crayon-plain-tag">function func(arg = "default"){
     return arg;
 }
 func("hello"); // "hello"
 func(); // "default"</pre><p></p>

<p>デフォルトパラメータは<pre class="crayon-plain-tag">=</pre>を用いて定義します。また、デフォルトパラメータはオプショナルパラメータと同様に扱われ、コールする際にパラメータを渡さなくともエラーにはならず、デフォルトの値が代入されます。</p>

<h4>レストパラメータ</h4>

<p>JavaScriptでは可変長パラメータを実現するために、<pre class="crayon-plain-tag">arguments</pre>オブジェクトを利用していました。しかしTypeScriptでは、ECMA-262 6th Editionの仕様の一つである、レストパラメータを利用できます。</p>

<p></p><pre class="crayon-plain-tag">function func(arg, ...args){
    return args;
}
func(0,1,2,3); // [1,2,3]</pre><p></p>

<p>レストパラメータは先頭に<pre class="crayon-plain-tag">...</pre>を付け、定義します。 また、レストパラメータが宣言できるのは宣言内の最後のパラメータのみで、値は配列として格納されます。</p>

<h4>ラムダ式</h4>

<p>最後にラムダ式です。JavaScriptの関数は関数内と外で<pre class="crayon-plain-tag">this</pre>の参照先が異なりました。よって、JavaScriptでは<pre class="crayon-plain-tag">this</pre>を変数に格納しておいて、その変数から参照する方法がよく使用されています。 次のコードでは<pre class="crayon-plain-tag">ringPallet</pre>関数にバインドされる<pre class="crayon-plain-tag">this</pre>の参照を<pre class="crayon-plain-tag">self</pre>にコピーし、戻り値の関数内で使用しています。</p>

<p></p><pre class="crayon-plain-tag">var Color = {
    code: ["#000", "#FFF", "#F00", "#0F0", "#00F"]
    , ringPallet: function( ){
        var self = this
          , index = 0;
        return function( ){
            var color = self.code[index];
            index = (index + 1) % self.code.length;
            return color;
        }
    }
 }
 var nextColor= Color.ringPallet();
 nextColor(); // "#000"
 nextColor(); // "#FFF"</pre><p></p>

<p>しかし、TypeScriptではラムダ式を使用することで<pre class="crayon-plain-tag">this</pre>の参照先を同一にすることができます。</p>

<p></p><pre class="crayon-plain-tag">var Color = {
    code: ["#000", "#FFF", "#F00", "#0F0", "#00F"]
    , ringPallet: function( ){
        var index = 0;
        return ( ) =&gt; {
            var color = this.code[index];
            index = (index + 1) % this.code.length;
            return color;
        }
    }
}</pre><p></p>

<p>ラムダ式は次のように<pre class="crayon-plain-tag">=&gt;</pre>を用いて記述します。</p>

<p></p><pre class="crayon-plain-tag">(arg) =&gt; {
    return this;
}</pre><p></p>

<p>このとき、変換されたJavaScriptは次のようになります。</p>

<p></p><pre class="crayon-plain-tag">var _this = this;
function(arg){
    return _this;
}</pre><p></p>

<p><pre class="crayon-plain-tag">this</pre>の参照先が<pre class="crayon-plain-tag">_this</pre> に格納され、ラムダ式内の<pre class="crayon-plain-tag">this</pre>は全てここを参照するようになります。</p>

<p>このラムダを使用することで<pre class="crayon-plain-tag">this</pre>の参照先を同一に保つことができ、イベントリスナーや<pre class="crayon-plain-tag">forEach</pre>、<pre class="crayon-plain-tag">sort</pre>のコールバックをスリムに記述することができます。</p>

<h2>型注釈</h2>

<p>冒頭で述べたとおり、型注釈はTypeScriptを特徴づける重要な機能の一つです。</p>

<p>型注釈にて静的型付を行うことで、コンパイラが整合性をチェックし、適合しているかどうかを検査してくれます。</p>

<p>TypeScriptで型注釈を行う場合、次のようにJavaScriptでの変数宣言の後にコロンで区切りその変数の型を指定します。</p>

<p></p><pre class="crayon-plain-tag">var value: string;</pre><p></p>

<p>このように型注釈をすることで、<pre class="crayon-plain-tag">value</pre>はstring型と認識されます。ある型で宣言された変数はその型の値しか代入することはできません。以下のコードはJavaScriptであれば何の問題もなく動作します。</p>

<p></p><pre class="crayon-plain-tag">var value;
value = "value";
value = 0;</pre><p></p>

<p>しかし、この<pre class="crayon-plain-tag">value</pre>がTypeScriptでString型に型注釈されていた場合、<pre class="crayon-plain-tag"></pre>を代入するコードでコンパイルエラーとなります。</p>

<p></p><pre class="crayon-plain-tag">var value: string;
value = "value";
value = 0; // コンパイルエラー</pre><p></p>

<p>型注釈をすることで、変数に特定の型を持つ値以外が代入できないように、制限することができます。制限を設けることで、存在しないメンバ関数にアクセスしてしまうミスなどを、事前に防ぐことができます。また、静的に検査されるため、型注釈が実行時のパフォーマンスを直接下げることはありません。</p>

<p>TypeScriptには次の基本型があります。型注釈にはこの基本型に加え、関数とオブジェクト、クラス、インターフェースが使用できます。</p>

<ul>
<li>number</li>
<li>string</li>
<li>boolean</li>
<li>Array </li>
<li>Enum</li>
<li>void</li>
<li>any</li>
</ul>

<p><strong>number/string/boolean</strong><br />
<pre class="crayon-plain-tag">number</pre>,<pre class="crayon-plain-tag">string</pre>,<pre class="crayon-plain-tag">boolean</pre>はそれぞれJavaScriptの<pre class="crayon-plain-tag">number</pre>,<pre class="crayon-plain-tag">string</pre>,<pre class="crayon-plain-tag">boolean</pre>と対応します。</p>

<p></p><pre class="crayon-plain-tag">var num: number = 0;
var str: string = "Hello," + ' World!';
var flag: boolean = false;</pre><p></p>

<h4>Array</h4>

<p><pre class="crayon-plain-tag">Array</pre>型には二つの表記法があります。一つは型の後に<pre class="crayon-plain-tag">[]</pre>を付ける方法、もう一つが<pre class="crayon-plain-tag">Array</pre>クラスを利用する方法です。</p>

<p></p><pre class="crayon-plain-tag">var nums: number[] = [0, 1, 2, 3, 4];
var strs: Array = ["foo", "bar"];</pre><p></p>

<p><pre class="crayon-plain-tag">Array</pre>クラスは相称型を利用しています。総称型については次回詳しく紹介します。</p>

<h4>Enum</h4>

<p>TypeScriptではEnumが導入され、これも型として扱うことができます。</p>

<p></p><pre class="crayon-plain-tag">enum Color {Red, Green, Blue};  // Red=0, Green=1, Blue=2
var color: Color = Color.Green; // 1
var colorName: string = Color[color]; // "Green"</pre><p></p>

<p>Enumの値は0から連続する整数値です。また、その値で参照することで文字列を取得することができます。<br />
多くの言語のEnumと同様に値を自分で決めることもできます。</p>

<p></p><pre class="crayon-plain-tag">enum Color {Red=1, Green=5, Blue};// Red=1, Green=5, Blue=6</pre><p></p>

<p>値を決める際は代入文を使用します。代入文がない場合は、前の要素の次の値になります。</p>

<h4>any</h4>

<p><pre class="crayon-plain-tag">any</pre>型は全ての型を指します。型が判断できない場合はこの<pre class="crayon-plain-tag">any</pre>型であると判断されます。 <pre class="crayon-plain-tag">any</pre>型は全ての型の値を格納でき、また、どの型にもキャストすることができます。</p>

<p></p><pre class="crayon-plain-tag">var anyVal: any;
anyVal = 0;        // ok
anyVal = "string"; // ok
var num: number = anyVal; // ok</pre><p></p>

<p><pre class="crayon-plain-tag">anyVal</pre>は<pre class="crayon-plain-tag">any</pre>型なので、数値や文字列などのどの型の値も書くできます。また、どの型にもキャスト可能で暗黙的に変換されます。<br />
上記のコードで<pre class="crayon-plain-tag">num</pre>は<pre class="crayon-plain-tag">number</pre>型を期待していますが、代入されているのは文字列です。しかし、<pre class="crayon-plain-tag">any</pre>型であるためにコンパイルエラーにはなりません。このよう理由から、極力<pre class="crayon-plain-tag">any</pre>型の利用は避けるべきです。</p>

<p>なお、TypeScriptで明示的にキャストするには <pre class="crayon-plain-tag">&lt;&gt;</pre> を使用します。</p>

<p></p><pre class="crayon-plain-tag">var num: number = anyVal;</pre><p></p>

<h4>関数とvoid</h4>

<p>関数の型を指定することができます。関数の型は、パラメータの型と戻り値の型をしていすることで表記します。</p>

<p></p><pre class="crayon-plain-tag">var func: (arg: string) =&gt; void;
func = function(arg: string): void{
    console.log(arg);
}
func = (arg: string):void =&gt; {
    console.log(arg);
}</pre><p></p>

<p>このように<pre class="crayon-plain-tag">(パラメータ名： パラメータの型) =&gt; 戻り値の型</pre>と表記します。また、<pre class="crayon-plain-tag">void</pre>型は値がないことを表し、関数の戻り値の型注釈のみで利用することが作法となっています。<br />
また、<pre class="crayon-plain-tag">function(パラメータ名： パラメータの型): 戻り値の型</pre>や、<pre class="crayon-plain-tag">(パラメータ名： パラメータの型):戻り値の型</pre>とすることで、関数宣言にパラメータや戻り値の型注釈をすることができます。</p>

<p>デフォルトパラメータは、オプショナルパラメータとしてあらわされます。よって次のコードの<pre class="crayon-plain-tag">defaultFunc</pre>関数と<pre class="crayon-plain-tag">optionalFunc</pre>関数の型は両方とも同じく<pre class="crayon-plain-tag">(arg?: string) =&gt; void</pre>となります。</p>

<p></p><pre class="crayon-plain-tag">function defaultFunc(arg: string = "default") {}
function optionalFunc(arg?: string){}
var func: (arg?: string) =&gt; void;
func = defaultFunc;  // ok
func = defaultFunc;  // ok</pre><p></p>

<h4>オブジェクト</h4>

<p>オブジェクトも型付けをすることができます。オブジェクトに型付けをすることで、そのオブジェクトにどんなプロパティがあるべきかを定義することができます。</p>

<p>次にコードでは、変数<pre class="crayon-plain-tag">obj</pre>はプロパティに<pre class="crayon-plain-tag">message</pre>と<pre class="crayon-plain-tag">string</pre>を持つオブジェクトであることを型付けしています。</p>

<p></p><pre class="crayon-plain-tag">var obj: { message: string; say: ()=&gt;;void};
obj = {
    message: "Hello"
    , say: function( ){
        console.log(this.message);
    }
    , more: "more"
}</pre><p></p>

<p>このように、オブジェクトの型付けを利用することで、存在しないプロパティを参照するミスを事前にチェックすることができます。</p>

<h2>型推論</h2>

<p>型注釈は制約を設け、コンパイラによるチェックを容易にしますが、すべてに注釈すると冗長に見えます。 TypeScriptは他の静的言語と同様に、ある程度型を推論して自動的に型付けをしてくれる型推論があります。</p>

<p>例えば次のコードでは、<pre class="crayon-plain-tag">str</pre>は文字リテラルで初期化しているためstring型であると推論されます。</p>

<p></p><pre class="crayon-plain-tag">var str = "Hello";
    str = 0; // エラー</pre><p></p>

<p>関数もある程度推論されます。 次のコードでは、<pre class="crayon-plain-tag">str</pre>関数のパラメータが<pre class="crayon-plain-tag">number</pre>型であり、<pre class="crayon-plain-tag">toString</pre>メンバ関数の戻り値の型は<pre class="crayon-plain-tag">string</pre>型であることから、変数<pre class="crayon-plain-tag">s</pre>は<pre class="crayon-plain-tag">string</pre>型であると推論されます。</p>

<p></p><pre class="crayon-plain-tag">function str(num: number){
    return num.toString();
}
var s = str(100);
s = 0;  // エラー</pre><p></p>

<p>このコードで注釈をしているのは<pre class="crayon-plain-tag">str</pre>関数のパラメータの一つだけです。この注釈を外すと<pre class="crayon-plain-tag">num</pre>は<pre class="crayon-plain-tag">any</pre>型となり、それ以上推論ができなくなり、<pre class="crayon-plain-tag">str</pre>関数の戻り値の型も<pre class="crayon-plain-tag">any</pre>型、変数<pre class="crayon-plain-tag">s</pre>の型も<pre class="crayon-plain-tag">any</pre>型になります。よって、0の代入はエラーになりません。</p>

<p>便利な型推論ですが、注釈を外し過ぎるとすべてが<pre class="crayon-plain-tag">any</pre>型となってしまい、静的型付けの恩恵を得られなくなってしまいます。そこで強くお勧めするのが<pre class="crayon-plain-tag">--noImplicitAny</pre>コンパイルオプションです。このオプションを付けると<pre class="crayon-plain-tag">any</pre>型に推論がなされた際に、コンパイルエラーとして通知してくれるようになります。 つまり、このオプションを利用することで、最小限の注釈ですべてがしっかり型付けされることを保証することができます。 しっかり型付けをすることで、コード補完などの支援も受けやすくなるので積極的に使用しましょう。</p>

<p>前回、Sublime Text 3上での開発環境を構築しました。この環境で<pre class="crayon-plain-tag">--noImplicitAny</pre>オプションを有効にするには、「Preferences」 &gt; 「Package Settings」 &gt; 「T3S」 &gt; 「Settings-User」の設定を次のように編集します。</p>

<p></p><pre class="crayon-plain-tag">{
    "local_tss":true,
    "error_on_save_only":false,
    "build_parameters":{
        "pre_processing_commands":[],
        "post_processing_commands":[],
        "output_dir_path":"none",
        "concatenate_and_emit_output_file_path":"none",
        "source_files_root_path":"none",
        "map_files_root_path":"none",
        "module_kind":"none",
        "allow_bool_synonym":false,
        "allow_import_module_synonym":false,
        "generate_declaration":false,
        
        //この"no_implicit_any_warning"をtrueにする
        "no_implicit_any_warning":true,
                    
        "skip_resolution_and_preprocessing":false,
        "remove_comments_from_output":false,
        "generate_source_map":false,
        "ecmascript_target":"ES5"
    }
}</pre><p></p>

<p><pre class="crayon-plain-tag">build_parameters.no_implicit_any_warning</pre>プロパティを<pre class="crayon-plain-tag">true</pre>に設定して、上書き保存をすることで、<pre class="crayon-plain-tag">--noImplicitAny</pre>コンパイルオプションを有効にすることができます。</p>

<h2>オーバーロード</h2>

<p>JavaScriptは多様性を積極的に活用する言語の一つです。とくにjQueryなどのライブラリでは多くの多様性を持ったメンバー関数が実装されています。<br />
もちろん、TypeScriptでも同様に実装することで多様性は実現できますが、そのままでは<pre class="crayon-plain-tag">any</pre>型になってしまうため、型注釈が必要です。<br />
TypeScriptは関数の実装に対して、シグネチャの異なる複数の宣言を持つことができます。これを利用することで関数のオーバーロードが可能になっています。</p>

<p>次のコードでは<pre class="crayon-plain-tag">render</pre>関数をオーバーロードしています。</p>

<p></p><pre class="crayon-plain-tag">function render(html: string, parent?: HTMLElement);
function render(elem: HTMLElement, parent?: HTMLElement);
function render(arg: any, parent: HTMLElement = document.body){
    if(typeof arg === "string"){
    var elem = document.createElement("div");
        elem.innerHTML = arg;
        while (elem.childNodes.length) {
            parent.appendChild(elem.firstChild);
        }
    }
    else{
        parent.appendChild(arg);
    }
}
render("<p>Hello, World!</p>");
render(document.createElement("div"));
render(0); // コンパイルエラー</pre><p></p>

<p>この<pre class="crayon-plain-tag">render</pre>関数は<pre class="crayon-plain-tag">(html: string, parent?: HTMLElement)=&gt;void</pre>、または、<pre class="crayon-plain-tag">(elem: HTMLElement, parent?: HTMLElement)=&gt;void</pre>の２つのシグネチャを持ちます。 最後の<pre class="crayon-plain-tag">render(0)</pre>は２つのシグネチャのどちらとも一致しないのでコンパイルエラーになります。</p>

<h2>まとめ</h2>

<p>今回は型注釈を中心に、変数や関数での注釈方法や、関数のオーバーロードなどを紹介しました。また、前回構築した開発環境で<pre class="crayon-plain-tag">--noImplicitAny</pre>コンパイルオプションを有効にし、より、TypeScriptの力を発揮できるようにしました。</p>

<p>型注釈をしっかり施すことによって、型の不一致から発生するバグを実行前に検知し、修正することができます。 これが、TypeScriptの大きな魅力の一つです。
ぜひ、コンパイルオプションを変更して<pre class="crayon-plain-tag">any</pre>型がでなるべくないようにコードを書いてみてください。</p>

<p>次回はクラスやインターフェース、総称型を紹介します。</p>
]]></content:encoded>
		
		<series:name><![CDATA[TypeScriptではじめる、モダンWebアプリケーション開発]]></series:name>
	</item>
		<item>
		<title>初めての方必見！TypeScriptでモダンなWebアプリケーション開発を始めよう</title>
		<link>/_iwate/7114/</link>
		<pubDate>Wed, 04 Jun 2014 00:00:58 +0000</pubDate>
		<dc:creator><![CDATA[谷口慈行]]></dc:creator>
				<category><![CDATA[プログラミング]]></category>
		<category><![CDATA[TypeScript]]></category>

		<guid isPermaLink="false">/?p=7114</guid>
		<description><![CDATA[連載： TypeScriptではじめる、モダンWebアプリケーション開発 (1)Webページで補助的に使用する用途で開発されたJavaScriptも、今ではWebになくてはならない重要な技術の一つです。特にSingle-...]]></description>
				<content:encoded><![CDATA[<div class="seriesmeta">連載： <a href="https://html5experts.jp/series/typescript-dev/" class="series-171" title="TypeScriptではじめる、モダンWebアプリケーション開発" data-wpel-link="internal">TypeScriptではじめる、モダンWebアプリケーション開発</a> (1)</div><p>Webページで補助的に使用する用途で開発されたJavaScriptも、今ではWebになくてはならない重要な技術の一つです。特にSingle-page ApplicationなどのモダンなWebアプリケーションではそのコード量も多くなります。JavaScriptの負担する領域が日々大きくなる中、様々なフレームワークやライブラリが日夜生まれ続けており、また、JavaScript自体を代替する言語、altJSが注目を集めています。</p>

<p>altJSの一つであるTypeScriptが4月2日にめでたくTypeScript 1.0となりリリースされました。今回は、このTypeScriptの特徴を絞って紹介し、実際にTypeScriptで開発できる環境を構築します。</p>

<h2>TypeScriptとは?</h2>

<p>TypeScriptはMicrosoft主導のもとオープンソースとして開発されており、CoffeeScriptやHaxe等と同じく、JavaScriptにコンパイルし、JavaScriptエンジン上で動作します。</p>

<p>Dartのように独自のVMはありませんが、開発環境が充実しており、入力補完が行えたり、ソースマップの利用でTypeScriptのコード上でのデバッグが可能です。</p>

<p>TypeScriptの特徴を3行でまとめると、</p>

<ul>
<li>JavaScriptのコードそのまま解釈でき、既存コードから開発をスタートできる。</li>
<li>また、クラスやインターフェース、モジュール化などでコンポーネント化がより容易になる。</li>
<li>かつ、型検査やインテリセンス、リッチデバッグ環境で大規模開発を助けてくれる。</li>
</ul>

<p>と、そんな言語です。</p>

<p>TypeScriptの基本的な文法仕様はJavaScriptと変わりません。なので、既存のJavaScriptのコードをそのままコピー＆ペーストしても差異なく動き、既存のコードを徐々にTypeScriptの機能で記述していくような開発スタイルが取れます。</p>

<h2>ここがTypeScriptのチャームポイント！</h2>

<p>私が注目しているTypeScriptの特徴は次の３つです。</p>

<ul>
<li>次世代JavaScriptの仕様</li>
<li>静的な型付けと構造的部分型</li>
<li>デバッグへの配慮</li>
</ul>

<p>TypeScriptにはClassなどの次世代JavaScript：ECMA-262 6th Editionで追加される最新機能にできるだけ近くした機能が提供されています。つまり次世代標準を先取りして利用しているので、将来ECMAScript6が標準化された際に自然に移行でき、また、今後、TypeScriptとJavaScriptの差異は小さくなっていくと考えられます。</p>

<p>次に、TypeScriptの名前にもある通り、<em>型</em>は欠かすことができない仕様です。静的な型付けと構造的部分型のおかげで、TypeScriptは名実ともに静的な型付け言語を好む開発者のためのaltJSであるといえます。</p>

<p>最後に、TypeScriptはデバッグ環境の充実に力を入れている言語です。ソースマップを出力できるので、ブラウザでのデバッグの際にTypeScriptコード上でデバッグすることができます。</p>

<h2>ClassやModuleが使える</h2>

<p>次世代JavaScriptで導入される仕様にClassとModuleがあります。TypeScriptではこれらの機能を先取りして導入しています。</p>

<p>Classは名のとおり、クラスを定義するための仕様です。「原稿の仕様：ECMA-262 5.1th Edition」でも<code>class</code>や<code>extends</code>などのキーワードが予約語になっています。次世代JavaScriptではこれらの機能が利用できるようになる予定で、様々なaltJSで仕様に若干のブレがあったクラス定義が一律のものになります。</p>

<p>クラスの定義は多くのオブジェクト指向言語と大差はありません。</p>

<p></p><pre class="crayon-plain-tag">class Person {
    name
    static kind = "Homo sapiens";
    constructor(name) {
        this.name = name;
    }
    walk(distance) {
        console.log(this.name + " walk " + distance + "meter.");
    }
    private think() {
        console.log(this.name + " is thinking...");
    }
}</pre><p></p>

<p>このようにクラスを定義すると次のようなJavaScriptのコードが生成されます。</p>

<p></p><pre class="crayon-plain-tag">var Person = (function () {
    function Person(name) {
        this.name = name;
    }
    Person.prototype.walk = function (distance) {
        console.log(this.name + " walk " + distance + "meter.");
    };
    Person.prototype.think = function () {
        console.log(this.name + " is thinking...");
    };
    Person.kind = "Homo sapiens";
    return Person;
})();</pre><p></p>

<p>標準的なJavaScriptでのクラスの実装です。また、出力されるJavaScriptコードではECMA-262 3rd、または5thで実行可能なコードを生成することができるので旧ブラウザ対応にも問題ありません。次世代JavaScriptの仕様と異なる部分は<code>private</code>と<code>public</code>の2つの識別子が挙げられます。このほかにもTypeScriptではインターフェイスの実装など独自に拡張している箇所がいくつか存在します。</p>

<p>Classと同様に導入されている新機能にModuleがあります。TypeScriptではモジュール、または、内部モジュールと呼ばれます。このモジュールを利用することで名前空間を実現でき、適切なカプセル化が施せるようになります。</p>

<p>モジュールは<code>module</code>キーワードを用いて次のように定義します。</p>

<p></p><pre class="crayon-plain-tag">module M {
    class A { }
    export class B { }
}
new M.A(); // エラー
new M.B();</pre><p></p>

<p>モジュール内に定義されたクラスや変数、関数などが利用できるのはそのモジュール内のみとなります。モジュールの外で利用したい場合は<code>export</code>キーワードを先頭におきます。</p>

<p>現在はクラスやモジュール、アロー関数などの次世代JavaScriptの仕様の導入が進んでいます。これらの機能は可能な限り、ECMA-262 3rdのコードを生成できるようになっているので次世代JavaScriptの仕様をいち早く試して、なおかつ、未対応のブラウザもカバーできるようなaltJSになりつつあります。これはとても魅力的なことではないでしょうか？</p>

<h2>静的型付けと構造的部分型</h2>

<p>TypeScriptの大きな特徴の一つとして、静的型付け言語であるということがあげられます。その名称にもなるくらいに重要視しており、次世代JavaScriptの機能以上にこだわりが感じられます。</p>

<p>つまり、TypeScriptはコンパイラによる型検査を好む開発者のための言語だといえます。Java、C#、Scalaなどの静的型付け言語を利用している、あるいは、静的型付け言語にメリットを感じる開発者がターゲットなのです。</p>

<p>TypeScriptでは、<code>number</code>、<code>string</code>、<code>boolean</code>、<code>Array</code>、<code>Enum</code>、<code>any</code>に関数の戻り値が<code>undefined</code>であることを示す<code>void</code>を含めた7つの基本型があります。</p>

<p>TypeScriptでの型注釈は次のように変数名の後にコロンで区切って行います。</p>

<p></p><pre class="crayon-plain-tag">var hoge:string;</pre><p></p>

<p><code>var</code>を先頭に書かなければならないので冗長に感じますが、JavaScriptのコードと共存させるためにこのような仕様になっています。</p>

<p>型注釈によって指定された型以外の型の値を代入するとエラーになります。</p>

<p></p><pre class="crayon-plain-tag">var hoge:string = "hoge";
hoge = 0; // エラー</pre><p></p>

<p>型注釈で<code>any</code>を指定するとJavaScriptと同様に全ての型を許容します。型を注釈しない場合は<code>any</code>型であると判断されます。</p>

<p>動的型付けと静的型付けのメリットの論点にサブタイピングがあります。サブタイピングには公称的部分型（nominal subtyping）、構造的部分型（structural subtyping）、ダックタイピング（duck typing）の3種類があります。そして、動的言語ではもっぱらダックタイピングが採用されており、JavaScriptもこのダックタイピングです。ダックタイピングとは、オブジェクトが期待通りの役割を果たせるなら、それが何であろうとかまわない手法です。</p>

<p>例えば、次のJavaScriptコードは期待通りに動きます。</p>

<p></p><pre class="crayon-plain-tag">var a = {
    method: function () { }
}
var b = {
    method: function () { }
}
function exec (obj) {
    obj.method();
}
exec(a);
exec(b);</pre><p></p>

<p><code>a</code>も<code>b</code>もメンバに<code>method</code>があるので、<code>exec</code>内の<code>method</code>のコールでエラーになることはありません。<code>a</code>と<code>b</code>の間には何の取り決めも約束事もありませんが、両方とも実行時に<code>method</code>を持っているので<code>exec</code>関数は気にしないのです。</p>

<p>しかし、これは静的言語ユーザの視点からするとなんとも落ち着かない状態です。何とか、<code>exec</code>に条件付けをして制約を設けたいところです。そこで、利用できるのが、公称的部分型と構造的部分型です。</p>

<p>公称的部分型は古くから静的言語で利用されているインターフェイスを用いる方法です。もちろん、TypeScriptでも利用できます。</p>

<p></p><pre class="crayon-plain-tag">interface I {
    method():void;
}
var a: I = {
    method: function () { }
}
var b: I = {
    method: function () { }
}
function exec (obj: I) {
    obj.method();
}
exec(a);
exec(b);</pre><p></p>

<p>メンバに<code>method</code>の実装を義務付けるインターフェイス<code>I</code>をつくり、<code>obj</code>および<code>a</code>、<code>b</code>に型注釈をすることで、<code>method</code>が確実に存在するように制約を設けることができました。</p>

<p>しかしこれでは、JavaScript本来のダックタイピングによる柔軟性が失われてしまったように感じます。</p>

<p>そこでTypeScriptは、Scalaなど比較的新しい言語ではおなじみの構造的部分型という手法を採用しています。これは代替する構造があればそれでよしとする手法です。</p>

<p>例えば先のコードの<code>b</code>の型を<code>any</code>に変えたものも正しいコードで、コンパイルエラーになりません。</p>

<p></p><pre class="crayon-plain-tag">interface I {
    method():void;
}
var a: I = {
    method: function () { }
}
var b: any = {
    method: function () { }
}
function exec (obj: I) {
    obj.method();
}
exec(a);
exec(b);</pre><p></p>

<p>これは、<code>b</code>も<code>I</code>と同様の構造を持っていることをコンパイラが確認できるため、エラーとみなしません。しかし、<code>b</code>の<code>method</code>の定義を削除するとエラーになります。</p>

<p>このように、TypeScriptはコンパイラによる型検査を導入しつつ、構造的部分型を採用し、JavaScript本来の持ち味をできるだけ生かすような言語仕様になっています。いかがでしょう、思わず「いいね！」を押したくなりませんか？</p>

<h2>ソースマップでそのままデバッグ！</h2>

<p>TypeScriptもHaxeなどのaltJSと同様に、実行コードとデバッグ対象のコードを紐づけるソースマップを出力できるため、TypeScriptコード上でデバッグすることができます。また、開発環境も充実しおり、インテリセンスや入力補完の恩恵を受けることができます。</p>

<p>ソースマップは<code>--sourcemap</code>オプションを付けることで出力することができます。</p>

<p><pre class="crayon-plain-tag">$ tsc --sourcemap app.ts</pre></p>

<p>ソースマップはModern IEやChromeなどの主要なブラウザで利用することができますが、利用にあたって設定する箇所があります。</p>

<p>Modern IEであれば、開発者ツールの「デバッガー」タブを開き対象のファイルを読み込みます。この時、tsファイルが読み込まれていればそのままTypeScriptでデバッグできます。もし、jsファイルが読み込まれている場合は図の赤枠で示す「ソースマップのロード」をオンにします。</p>

<div id="attachment_7119" style="width: 934px" class="wp-caption alignnone"><a href="https://html5experts.jp/wp-content/uploads/2014/05/load_js_sourcemap.png" data-wpel-link="external" target="_blank" rel="follow external noopener noreferrer"><img src="/wp-content/uploads/2014/05/load_js_sourcemap.png" alt="Modern IEでのソースマップの利用" width="924" height="456" class="size-full wp-image-7119" srcset="/wp-content/uploads/2014/05/load_js_sourcemap.png 640w, /wp-content/uploads/2014/05/load_js_sourcemap-300x148.png 300w, /wp-content/uploads/2014/05/load_js_sourcemap-207x101.png 207w" sizes="(max-width: 924px) 100vw, 924px" /></a><p class="wp-caption-text">Modern IEでのソースマップの利用</p></div>

<p>Chromeの場合はDeveloper Toolsの「Settings」を開き、図の赤枠で示す「Enable JavaScript source maps」をオンにします。</p>

<div id="attachment_7116" style="width: 796px" class="wp-caption alignnone"><a href="https://html5experts.jp/wp-content/uploads/2014/05/enable_js_sourcemap.png" data-wpel-link="external" target="_blank" rel="follow external noopener noreferrer"><img src="/wp-content/uploads/2014/05/enable_js_sourcemap.png" alt="Chromeでのソースマップの利用" width="786" height="375" class="size-full wp-image-7116" srcset="/wp-content/uploads/2014/05/enable_js_sourcemap.png 640w, /wp-content/uploads/2014/05/enable_js_sourcemap-300x143.png 300w, /wp-content/uploads/2014/05/enable_js_sourcemap-207x98.png 207w" sizes="(max-width: 786px) 100vw, 786px" /></a><p class="wp-caption-text">Chromeでのソースマップの利用</p></div>

<p>これで、TypeScriptコード上でブレイクポイントを置いたり、値をウォッチしたりとリッチなデバッグをすることができます。</p>

<div id="attachment_7115" style="width: 934px" class="wp-caption alignnone"><a href="https://html5experts.jp/wp-content/uploads/2014/05/debug_on_ts.png" data-wpel-link="external" target="_blank" rel="follow external noopener noreferrer"><img src="/wp-content/uploads/2014/05/debug_on_ts.png" alt="TypeScriptコード上でのブレイクポイント" width="924" height="456" class="size-full wp-image-7115" srcset="/wp-content/uploads/2014/05/debug_on_ts.png 640w, /wp-content/uploads/2014/05/debug_on_ts-300x148.png 300w, /wp-content/uploads/2014/05/debug_on_ts-207x101.png 207w" sizes="(max-width: 924px) 100vw, 924px" /></a><p class="wp-caption-text">TypeScriptコード上でのブレイクポイント</p></div>

<h2>TypeScript開発環境の構築</h2>

<p>最後に、入力補完やシンタックスハイライトがあり、TypeScriptでの開発がとてもはかどる環境を整えます。</p>

<p>開発環境の選択肢は次の3つがあります。</p>

<ul>
<li>Visual Studio 2013 / 2012</li>
<li>IntelliJ IDEA / WebStorm</li>
<li>Sublime Text 3</li>
</ul>

<p>ここでは、OSを問わず利用でき、さらにWeb開発での利用者も多いSublime Textで構築します。</p>

<h3>事前準備</h3>

<p>Node.jsとnpm、Sublime Text 3をインストールしておいて下さい。</p>

<p><strong>1. TypeScriptのインストール</strong></p>

<p>TypeScriptと周辺ツールをインストールします。</p>

<p><pre class="crayon-plain-tag">npm install -g typescript typescript-tools</pre></p>

<p><strong>2. T3Sのインストール</strong></p>

<p><a href="https://github.com/Railk/T3S" title="T3S" target="_blank" data-wpel-link="external" rel="follow external noopener noreferrer">T3S</a>はSublime Text 3のプラグインで、TypeScriptの入力補完・エラーチェックなどができます。</p>

<p>Sublime Textを開きツールバーから「Preferences」の「Browse Packages…」を選択します。開いたフォルダをターミナルで開きます。Windowsなら、<code>Shift</code>+<code>右クリック</code>で現れるコンテキストメニューから「コマンドウィンドウをここで開く」を選択のがおすすめです。</p>

<p>ここで、githubからパッケージをクローンします。</p>

<p><pre class="crayon-plain-tag">$ git clone https://github.com/Railk/T3S.git</pre></p>

<p><strong>3. SublimeOnSaveBuildのインストール</strong></p>

<p>2.に続けて<a href="https://github.com/alexnj/SublimeOnSaveBuild" title="SublimeOnSaveBuild" data-wpel-link="external" target="_blank" rel="follow external noopener noreferrer">SublimeOnSaveBuild</a>もクローンします。SublimeOnSaveBuildはaltJSやCSSプリプロセッサなどを保存と同時にコンパイルするプラグインです。</p>

<p><pre class="crayon-plain-tag">$ git clone https://github.com/alexnj/SublimeOnSaveBuild.git</pre></p>

<p><strong>4. 設定</strong></p>

<p>最後に設定を行います。まず、Sublime Textを再起動します。再起動後、SublimeOnSaveBuildプラグインを設定してファイルを保存した際に自動でビルドするように設定します。</p>

<p>「Preferences」\&gt;「Package Settings」\&gt;「SublimeOnSaveBuild」\&gt;「Settings-User」を開き、次の設定をコピーします。</p>

<p></p><pre class="crayon-plain-tag">{
    "filename_filter": "\\.(ts|css|js|sass|less|scss)$",
    "build_on_save": 1
}</pre><p></p>

<p>次にT3Sプラグインを設定して、ソースマップをビルドするようにします。</p>

<p>「Preferences」\&gt;「Package Settings」\&gt;「T3S」内の「Settings-Default」の設定を同階層の「Settings-User」にコピーします。コピーした設定の<code>generate_source_map</code>の項目を<code>false</code>から<code>true</code>に変更します。</p>

<p></p><pre class="crayon-plain-tag">{
    "local_tss":true,
    "error_on_save_only":false,
     "build_parameters":{
     "pre_processing_commands":[],
     "post_processing_commands":[],
     "output_dir_path":"none",
     "concatenate_and_emit_output_file_path":"none",
     "source_files_root_path":"none",
     "map_files_root_path":"none",
     "module_kind":"none",
     "allow_bool_synonym":false,
     "allow_import_module_synonym":false,
     "generate_declaration":false,
     "no_implicit_any_warning":false,
     "skip_resolution_and_preprocessing":false,
     "remove_comments_from_output":false,
     "generate_source_map":true,
     "ecmascript_target":"ES3"
     }
 }</pre><p></p>

<p><strong>5. 確認</strong></p>

<p>以上で、環境構築は終了です。tsファイルを作成して確認してみます。</p>

<p>app.tsを作成して簡単なクラス：<code>A</code>を作成してみます。<code>A</code>はインスタンス変数を1つとインスタンス関数を2つ持っています。この<code>A</code>のインスタンス<code>a</code>を作成し、<code>.</code>を打つと下図のように入力補完が現れます。</p>

<div id="attachment_7118" style="width: 590px" class="wp-caption alignnone"><a href="https://html5experts.jp/wp-content/uploads/2014/05/intellisense.png" data-wpel-link="external" target="_blank" rel="follow external noopener noreferrer"><img src="/wp-content/uploads/2014/05/intellisense.png" alt="入力補完" width="580" height="423" class="size-full wp-image-7118" srcset="/wp-content/uploads/2014/05/intellisense.png 580w, /wp-content/uploads/2014/05/intellisense-300x218.png 300w, /wp-content/uploads/2014/05/intellisense-207x150.png 207w" sizes="(max-width: 580px) 100vw, 580px" /></a><p class="wp-caption-text">入力補完</p></div>

<p>さらに、エラーが発生した際には下図のようにエラーの発生した箇所がハイライトされます。</p>

<div id="attachment_7117" style="width: 639px" class="wp-caption alignnone"><a href="https://html5experts.jp/wp-content/uploads/2014/05/error.png" data-wpel-link="external" target="_blank" rel="follow external noopener noreferrer"><img src="/wp-content/uploads/2014/05/error.png" alt="エラー箇所のハイライト" width="629" height="310" class="size-full wp-image-7117" srcset="/wp-content/uploads/2014/05/error.png 629w, /wp-content/uploads/2014/05/error-300x147.png 300w, /wp-content/uploads/2014/05/error-207x102.png 207w" sizes="(max-width: 629px) 100vw, 629px" /></a><p class="wp-caption-text">エラー箇所のハイライト</p></div>

<p>ファイルを保存すると自動でコンパイルされます。 デフォルトのビルド設定を使っているので、jsファイルとmapファイルはソースコードと同じ階層に出力されます。</p>

<div id="attachment_7120" style="width: 775px" class="wp-caption alignnone"><a href="https://html5experts.jp/wp-content/uploads/2014/05/outs.png" data-wpel-link="external" target="_blank" rel="follow external noopener noreferrer"><img src="/wp-content/uploads/2014/05/outs.png" alt="出力ファイル" width="765" height="536" class="size-full wp-image-7120" srcset="/wp-content/uploads/2014/05/outs.png 640w, /wp-content/uploads/2014/05/outs-300x210.png 300w, /wp-content/uploads/2014/05/outs-207x144.png 207w" sizes="(max-width: 765px) 100vw, 765px" /></a><p class="wp-caption-text">出力ファイル</p></div>

<h2>まとめ</h2>

<p>今回はTypeScriptの魅力を3点に絞って大まかに紹介しました。また、Windows・Mac・Linuxで利用できる充実した開発環境も整えました。</p>

<p>ソースマップも出力されて、開発環境もここまで整っているなら、利用してもいいかなという気持ちになっていただけたでしょうか？今までのJavaScriptコードもそのまま動くので、まずは、ただコピーして要所要所に型注釈をいれることから初めて見て下さい。</p>

<p>次回からは、TypeScriptの記法を詳しく紹介していきますので、お楽しみに！</p>
]]></content:encoded>
		
		<series:name><![CDATA[TypeScriptではじめる、モダンWebアプリケーション開発]]></series:name>
	</item>
	</channel>
</rss>
