TypeScript入門 その3

TypeScript入門3回目の今回は、データ型の中でも、前回紹介できなかった列挙型(enum)、タプルや関数オブジェクトあたりについて説明しようと思います。

1. 列挙型(enum)
列挙型(enum)とは、あらかじめ決められた値のみを取ることができるデータ型です。例えば、こんな感じです。

enum Signal {
 Red, Yellow, Blue }; let red = Signal.Red; let yellow = Signal.Yellow; let blue = Signal.Blue; console.log(red); // 0 console.log(yellow); // 1 console.log(blue); // 2 // let green = Signal.Green // コンパイルエラー!

このようにして定義された変数signalは、Red, Yellow, Blueのいずれかしか代入することが出来なくなっています。
また、enumはデフォルトでは内部では0から始まる整数を取るようになっていますが、

enum Signal {
  Red = 2,
  Yellow = 3,
  Blue = 4
};

というように、定義するときに取る値を変更することもできます(数値だけでなく、文字列を入れたりもできます)。
ところで、最近ではenumを使わない方がいいという意見もあるようです。
enumを使わない書き方としては、こんな感じです。

const Signal = { 
  Red: 0,
  Yellow: 1,
  Blue: 2
} as const;
type Signal = typeof Signal[keyof typeof Signal];
let red = Signal.Red;
console.log(red);  // 0

このような有限集合のデータ型をUnion型と言います。
TypeScriptの経験が浅い自分はenumのデメリットを把握しきれてないのですが、enumはJavaScriptとの互換性がないというのは確かにありますね(コンパイル後のソースを見ると一目瞭然)。

2. タプル
次は、複数の型の値をまとめて持つことができるタプルというものを紹介します。
配列のように複数のデータ型を宣言することで定義できます。
例えば、こんな感じです。

let person: [string, number, string];
person = ["Taro", 26, "Tokyo"];
console.log(person[0]); // Taro
console.log(person[1]); // 26
console.log(person[2]); // Tokyo
person[1] = 30; // OK
person[1] = "30"; // コンパイルエラー

とはいえ、この書き方だと何を表しているかわからなくなりがちなので、下記のような使い方の方がわかりやすいかもです。後、先ほどのenumももちろん要素にすることができます。

type name = string;
type age = number;
type address = string;
enum gender {male, female};

let person: [name, age, address, gender];
person = ["Taro", 26, "Tokyo", gender.male];

3. 関数オブジェクト

TypeScriptでも、JavaScriptと同じように関数の定義を行えますが、やはりそこはTypeScript。引数と戻り値に型を指定することができます。

function multiple(a:number, b:number):number {
  return a * b;
}
multiple(5, 3); // 15
multiple(5, "3"); // コンパイルエラー

こんな感じです。
また、TypeScriptでは下記のようにオプション引数を使うことができます。

function multiple(a:number, b:number, c?:number):number {
  if (c) {
    return a * b * c;
  }
  return a * b;
}
multiple(5, 3); // 15
multiple(5, 3, 4); // 60

後は、同じ名前の違う型で定義された関数も定義することができます。いわゆるオーバーロードです。

function add(a:string, b:string):string;
function add(a:number, b:number):number;

function add(a:any, b:any):any {
    if (typeof a === "string" && typeof b === "string") {
        return a + ":" + b;
    }
    return a + b;
}
add("Hello", "World"); // Hello:World
add(7, 4); // 11
add("Hello", 4); // コンパイルエラー

 

今日はこの辺りで。
次回最終回(予定)はクラスとかのオブジェクト指向に関する話題を紹介しようと思います。

TypeScript入門 その2

前回のTypeScript入門その1に続いて、第2回の今回は、主にデータ型などを説明しようと思います。

1. 主要なデータ型
基本的なデータ型は、次の3つです。
・boolean
取ることができる値はtrueかfalseのどちらかだけです。
・number 
数値を値に取ることができます。整数、小数の区別はありません。
・string
文字列を値に持つことができます。

変数を宣言する時は、下記のようにして型とともに宣言します。

let enabled:boolean;
let money:number;
let name:string;
enabled = true;
money = 100;
name = "Ichiro";

money = "ABC";   // これはダメ。コンパイル時にエラーになります。

このように型を宣言すると、その変数には型に当てはまる値以外は入れられなくなります。JavaScriptでは10 == “10”がtrueになったりということもありましたが、TypeScriptではそもそも比較自体ができなくなります。
とはいえ、何らかの理由で型を指定したくない場合も場合によってはあるかと思います。このような場合はlet value:anyという風にany型を使うことでどのような型でも代入できるようになります。JavaScriptで書かれたソースをTypeScriptに書き換える場合なんかでたまに使うこともあるかもです。

2. 変数宣言の指定子
先ほどの変数宣言の例ではletを使って宣言しましたが、varだと関数の中での宣言なら関数内で、それ以外ならグローバルで使えるようになりますが、letは宣言された構文内のみがスコープになります。
varよりはletを使った方が想定外のところで値が書き換わるようなことがなくなるので、varにしなければいけない理由がある場合以外はletを使った方がいいと思います。
ちなみに、letはJavaScriptではES6から使えるようになりました。
また、変数宣言ではvarとletですが、定数宣言ではconstを使います。constで宣言されると、それ以降値の変更が一切できなくなります。
最近letも使わずconstだけを使うべきだという記事も見ましたが、確かに値を変更することがありえない場合はconstを使うべきですが、letでないと実装しづらいケースも多々あると思うので、個人的には「そこまでこだわらなくてもいいのでは」派です。

3. 配列
TypeScriptにも、JavaScriptと同じように配列は存在します。配列の宣言は下記のように行います。

let data:number[];
data = [1, 1, 2];
data.push(3);
console.log(data);   // 1,1,2,3
data.push("xyz");    // だからダメだってば

このように、配列もどんな型を要素に入れられるかの宣言を行います。なので、配列の要素に指定した型でないものを入れようとするとエラーになります。

この他にも、列挙型(enum)やタプルについても説明したかったのですが、次回にします。

TypeScript入門その1

  1. AltJSとは
    Webプログラミングのサーバー側言語はPHP、Java、Python、Ruby、・・・とたくさんありますが、フロントエンド側の言語となると、ほぼJavaScript一択。しかしJavaScriptにも下記のような問題点があったりします。
    ・型付けが自由すぎてそれに由来する想定外の問題が起きやすい(例えば1==”1″がtrueになったり)
    ・オブジェクト指向が独特(プロトタイプベース)
    ・スコープを絞りにくいそこで、最近ではこう行った問題を解決するために、より実装しやすいプログラミング言語(AltJSと言います)で実装してJavaScriptに変換するというのが流行りになりつつあります。
    というわけで、これから何回かに渡って代表的な AltJSの1つであるTypeScriptについて紹介していこうと思います。
  2. TypeScriptの特徴
    TypeScriptは2012年にマイクロソフトによって開発された言語で、下記の特徴を持っています。
    ・JavaScriptのスーパーセットである(JavaScriptの機能はTypeScriptでも使える)
    ・静的型付けの言語である(数値型の変数に文字列を代入したりするとエラーになる)
    ・クラスやインターフェースなど一般的なオブジェクト指向の機能を持っている(クラスについてはJavaScriptでもES6から使えるようになりましたが)
  3. TypeScriptの環境構築
    まず前提として、npmが使える環境であるとします。とりあえず、Windowsならコマンドプロンプトで、MacならiTerm2で”npm -v”と打ってみて、バージョンが出てくればOKです。入っていない人はこちらを参考にしてNode.jsとnpmをして下さい。
    次に、TypeScriptをインストールします。
    npm install -g typescript
    インストールし終わったら、とりあえず下記の内容をコピーして、.tsを拡張子につけたファイル名(例えばhello.ts)で保存して下さい。

    class Hello {
      public name: string;
      constructor(name: string) {
        this.name = name;
      }
    }
    
    let user = new Hello("World");
    console.log("Hello " + user.name);

    そしたら、”tsc hello.ts”で保存したファイルをコンパイルすればhello.jsというJavaScriptのファイルができているはずです。
    後は、HTMLに埋め込んでブラウザで開けば、検証ツールで”Hello World”と出力されることが確認できますし、node hello.jsでターミナル上で出力を確認してもいいでしょう。次回はTypeScriptで使えるデータ型などについて説明しようと思います。