メニューを閉じる

テクノデジタルグループ

メニューを開く

2016.05.11

プログラミング

JavaScriptよさらば。「TypeScript」で始めるECMAScript 2015

はじめまして、WebアプリケーションエンジニアのKです。

昨今の大規模Webサービスに生のJavaScriptで挑むには激しい辛みを覚える次第です。
そこで、同じく疲弊されてる皆さんに朗報です!

「TypeScript」をご存知でしょうか。

TypeScriptはECMAScript 2015(ECMAScript 6)に静的型付けを加えたスーパーセットであり、
ECMAScript 2015は去年6月に勧告された次世代のJavaScriptの中核仕様です。

今現在、巷のブラウザで動作するJavaScriptは一つ前のECMAScript 5の仕様が主流ですが、
Google Chrome、FireFox、Safari、Edge(IE11はNO)の最新版では、ECMAScript 2015が
動作するようになってきています。

TypeScriptはECMAScript 2015の仕様を
現行のJavaScriptコードにトランスパイルする機能を備えており、
いずれ使うことがでできる新しい仕様を先取りして利用することができます。

フロントエンド界隈は横文字が多いので、いったんまとめます。

  • TypeScript
    • 静的型付けを加えたECMAScript 2015のスーパーセット。
    • Alt JSなのでそのままでは動作しない。
    • ECMAScript 5にトランスパイラして使う。
  • ECMAScript(ES)
    • JavaScript系スクリプト言語の中核仕様を標準化したもの。
  • ECMAScript 2015
    • 別名、ECMAScript 6。2015年6月に勧告された次世代の仕様。
    • 最新版のGoogle Chrome、FireFox、Safari、Edgeではそこそこ動作する。
      詳しくはcompat-table/es6参照
  • ECMAScript 5(JavaScript)
    • 今現在、主流となっているJavaScriptのベースとなる仕様。
  • スーパーセット
    • 互換性を持つこと。
  • Alt JS
    • Altnative JavaScriptの略でJavaScriptを効率よく開発するための代替言語。
    • ブラウザで動作させるためにはECMAScript 5などにトランスパイルする必要がある。
    • TypeScriptの他に、BabelやCoffeeScriptなどがある。
  • トランスパイル
    • あるコードを、ブラウザで動作する形のJavaScriptに変換すること。

このTypeScriptとECMAScript 2015がとにかくスゴイので一部を紹介させていただきます。

TypeScriptをJavaScriptにトランスパイルする(Macでの例)

コードを紹介する前に、トランスパイルの方法を記載しておきます。
コンパイルが必要なことに抵抗がある人がいるかもしれませんが簡単です!

  1. Node.jsをインストールする
     1-1. Homebrewをインストール
    /usr/bin/ruby -e "$(curl -fsSL https://raw.githubusercontent.com/Homebrew/install/master/install)"
     1-2. nodebrewをインストール
    brew install nodebrew
     1-3. nodebrewのパスを通す(~/.bash_profileに追記)
    export PATH=$HOME/.nodebrew/current/bin:$PATH
     1-4. 設定ファイルを再読み込み
    source ~/.bash_profile
     1-5. Node.jsをインストール
    nodebrew install-binary stable
     1-6. 使用するNode.jsのバージョンを設定
    nodebrew use stable
    私が手元で動かしたときのnodeとnpmのバージョンは以下のとおりです
    node -v // v5.10.1
    npm -v // 3.8.3
  2. TypeScriptをインストールする
    npm install -g typescript
  3. プロジェクトフォルダを作成して移動する
    mkdir ~/tsc_sandbox && cd $_
  4. TypeScriptの設定ファイル(tsconfig.json)を作成する
    tsc --init
  5. コードを書く(ファイルの拡張子は.tsです)
  6. コンパイルする
    tsc -p .
  7. jsを実行して動作確認する(Macでは以下のコマンドで実行できます)
    osascript -l JavaScript sample.js

TypeScript + ECMAScript 2015で使用可能になる新たな構文

  • 変数の静的型付け
  • let・constキーワードによる変数宣言
  • classキーワードによるクラス宣言
  • 関数のオプション引数・デフォルト引数
  • 関数の可変長引数
  • アロー関数による関数宣言
  • 繰り返し構文
  • スプレッド演算子
  • 分割代入
  • テンプレートリテラル

変数の静的型付け

TypeScriptの売りはなんといっても静的型付けです。
静的型付け言語のメリットとして次が挙げられます。

  • コンパイル時エラーによるバグの早期発見
  • 型定義による可読性の向上
  • IDEのコード補完による恩恵が大きい

TypeScriptで使用できる型の使用例を示します。
型は変数名の後に: 型名と記述します。

// Boolean
let isDone: boolean = false;

// Number
let decimal: number = 6; 
let hex: number = 0xf00d; 
let binary: number = 0b1010; 
let octal: number = 0o744;

// String
let color: string = "blue";
name = 'red';

// Array
let list: number[] = [1, 2, 3];
let list: Array<number> = [1, 2, 3];

// Tuple
let x: [string, number];

// Enum
enum Color {Red, Green, Blue};
let c: Color = Color.Green;

// Any
let notSure: any = 4;
notSure = "maybe a string instead";
notSure = false;

// Void
function warnUser(): void {
  alert("This is my warning message");
}

// Type assertions
let someValue: any = "this is a string";
let strLength: number = (<string>someValue).length;

let・constキーワードによる変数宣言

ECMAScript 2015はletconstキーワードによって宣言された変数は、
ブラケット内{}でブロックスコープを有効にできます。

function f(input: boolean) {
  let a = 100;

  if (input) {
    let b = a + 1; // aは参照可能
    return b;
  }

  // bはブロックスコープ外なので参照不可
  return b;
}

letは変数、constは定数を宣言するときに使用します。varはもう使用しません。

let hoge: number = 1;
hoge = 2; // 再代入可能

const fuga: number = 1;
fuga = 2; // 再代入不可

classキーワードによるクラス宣言

ES 5のJavaScriptでもprototypeを使ってクラスのようなものを書くことはできましたが、
ES 2015からはJava使いには見慣れたコードスタイルでクラス宣言を書くことができます。

class Greeter {
    greeting: string;
    constructor(message: string) {
        this.greeting = message;
    }
    greet() {
        return "Hello, " + this.greeting;
    }
}

let greeter = new Greeter("world");

なお、ES 5のprototypeでクラスのようなもの書くとこうなります。
まだなんとか見れますが、継承を実現しようとするとかなり複雑になります。

var Greeter = (function () {
    function Greeter(message) {
        this.greeting = message;
    }
    Greeter.prototype.greet = function () {
        return "Hello, " + this.greeting;
    };
    return Greeter;
}());

var greeter = new Greeter("world");

関数のオプション引数・デフォルト引数

必須ではない引数については、変数名に?を付けることでオプション引数とすることができます。
ES 5までは、関数の引数の数が異なってもエラーとはならず、入るだけ入れるという振る舞いでしたが、
ES 2015からは引数の数が異なるとエラーになります。

function buildName(firstName: string, lastName?: string) {
    if (lastName)
        return firstName + " " + lastName;
    else
        return firstName;
}

let result1 = buildName("Bob");                  // 引数2はオプションなのでOK
let result2 = buildName("Bob", "Adams", "Sr.");  // 引数が3つなのでエラー
let result3 = buildName("Bob", "Adams");         // 引数が2つなのでOK

変数名に= "デフォルト値"を指定することで、引数にデフォルト値を与えることができます。

function buildName(firstName: string, lastName = "Smith") {
    return firstName + " " + lastName;
}

let result1 = buildName("Bob");                  // "Bob Smith"
let result2 = buildName("Bob", undefined);       // undefinedもデフォルト引数が適用される。"Bob Smith"
let result3 = buildName("Bob", "Adams", "Sr.");  // 引数が3つなのでエラー
let result4 = buildName("Bob", "Adams");         // "Bob Adams"

関数の可変長引数

変数名にスプレッド演算子...を付けることで、引数の数が未定の場合でも値を受け取ることができます。

function buildName(firstName: string, ...restOfName: string[]) {
    return firstName + " " + restOfName.join(" ");
}

let employeeName = buildName("Joseph", "Samuel", "Lucas", "MacKinzie");

アロー関数による関数宣言

関数型言語によく見るラムダ式のような書き方で関数を宣言できます。
functionを省略できる他、JavaScriptを書く上でよく問題となる
呼び出し元によってthisの値が変わる振る舞いを解消してくれます。

class MyClass {
    private status = "blah";

    public run = () => {
        alert(this.status); // アロー関数内で使用されるthisは一律、MyClassのインスタンスを指します
    }
}
var x = new MyClass();

繰り返し構文

Arrayやstring型などで簡単に値の取り出しを行うことができます。
for..ofはリストの値を、for..inはリストのキーを取り出します。

let someArray = [1, "string", false];

for (let entry of someArray) {
    console.log(entry); // 1, "string", false
}

スプレッド演算子

関数の可変長引数で出てきましたが、スプレッド演算子...を付けることで、
配列を展開して利用することができます。
用途としては次のようになります。

  • 関数の引数に配列を割り当てる
  • 配列リテラルの一部に配列を割り当てる
  • 分割代入の一部に可変長配列を割り当てる
function sum(...array: number[]) { }

let args: number[] = [0, 1, 2];
// 関数呼び出し
sum(...args);
// 配列リテラル
let hoge: number[] = [...args, 0, 1, 2]
// 分割代入
let [a, b, c, ...fuga] = [1, 2, 3, 4, 5]

console.log(fuga) // 4,5

分割代入

配列やオブジェクトから値を取り出して、別個の変数に割り当てることを分割代入といいます。

// 配列を分割代入する
let [a1, a2] = [1, 2]
// オブジェクトを分割代入する
let {b1, b2} = {b1: 1, b2: 2}

console.log(a1) // 1
console.log(a2) // 2
console.log(b1) // 1
console.log(b2) // 2

テンプレートリテラル

式の埋め込みができるようになった文字列リテラルです。
使用するにはバッククォート`で文字列を囲みます。
変数、式、改行コードなどを直感的に指定することができます。

let fullName: string = 'Bob Bobbington';
let age: number = 37;
let sentence: string = `Hello, my name is ${fullName}.

I'll be ${age + 1} years old next month.`

ES 5で書くとこうなります。ダブルクォートの数があってるか不安になることはもうありません。

var fullName = 'Bob Bobbington';
var age = 37;
var sentence = "Hello, my name is " + fullName + ".\n\nI'll be " + (age + 1) + " years old next month.";

 

 

 

簡単な内容となりましたが、紹介は以上です。

いかがでしたでしょうか、これでもまだTypeScript Handbookの3割程度しか紹介できていませんが、
TypeScriptとECMAScript 2015の魅力が伝われば幸いです。

ぜひみなさんの職場にTypeScriptを普及してください!それでは。


【記事への感想募集中!】

記事への感想・ご意見がありましたら、ぜひフォームからご投稿ください!
  • こんな記事が読んでみたい、こんなことが知りたい、調べてほしい!という意見も募集中!
  • いただいた感想は今後の記事に活かしたいと思います!

感想フォームはこちら


【テクノデジタルではエンジニア/デザイナーを積極採用中です!】

下記項目に1つでも当てはまる方は是非、詳細ページへ!
  • 自分でアプリを作ってみたい
  • ITで世の中にワクワクを生み出したい
  • 使いやすさ、デザインにこだわったWebサイトを開発したい

採用情報の詳細はこちら


Qangaroo(カンガルー)

  • 徹底した見やすさと優れた操作性で、テストの「見える化」を実現。
  • テストの進捗が見える。開発がスマートに進む。
  • クラウド型テスト管理ツール『Qangaroo(カンガルー)』

【テクノデジタルのインフラサービス】

当社では、多数のサービスの開発実績を活かし、
アプリケーションのパフォーマンスを最大限に引き出すインフラ設計・構築を行います。
AWSなどへのクラウド移行、既存インフラの監視・運用保守も承りますので、ぜひご相談ください。
詳細は下記ページをご覧ください。

https://www.tcdigital.jp/infrastructure/

最近の記事