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); // コンパイルエラー

 

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