アプリケーション開発をする際、プログラミング言語としてJavaScriptの知識は必須になります。
しかし、JavaScriptは変数の型を自動で定義するため、多少曖昧なコードでも実行できてしまいます。そのため、大規模開発では型に関する問題が発生しやすいという側面があります。
そこで登場するのがTypeScriptです。
TypeScriptは、JavaScriptの弱点を補うことを目的として作られたaltJSの一種です。
altJSとは、JavaScriptに変換して実行することを前提としたプログラミング言語の総称です。
TypeScriptは、その中でも特に広く利用されています。
そこで今回は、TypeScriptの基礎について書いていきます。
なお、JavaScriptの基礎は理解しているものとして進めます。
TypeScript学習の準備
TypeScriptを簡単に試す方法として、TypeScript Playgroundがあります。
1. TypeScript Playgroundを開く
まず、以下のページにアクセスしてください。
TypeScript Playgroundでは、ブラウザ上でTypeScriptのコードを記述し、そのコードがどのようなJavaScriptに変換されるのかを確認できます。
2. TypeScriptを実行する
TypeScript Playgroundを開くと、左側にTypeScriptのコードを入力するエリアがあります。
左側にTypeScriptのコードを入力すると、右側にJavaScriptへ変換されたコードが表示されます。
コードを実行する場合は、画面上にあるRunボタンをクリックします。
実行結果は、Google Chromeの場合、デベロッパーツールのConsoleタブから確認できます。
Chromeでデベロッパーツールを開くには、ページ上で右クリックして「検証」を選択する方法などがあります。
デベロッパーツールを開いたら、Consoleと書かれているところをクリックしてください。
そこからTypeScriptコードの実行結果を確認できます。
以上のようにして、TypeScriptを実行することができます。
初心者のうちは短いコードを入力するところから始めることになるので、この方法で学習した方がよいでしょう。
変数とデータ型について
変数とは、いわゆる値を保管しておくための入れ物です。
TypeScriptでは、変数であることをletを使って宣言します。
基本的には以下のように記述します。
let 変数の名前: データ型 = 初期値;
ここで、変数に代入する値の種類には、数値や文字列などがあります。
変数に代入する値の種類を決めたい場合、変数にデータ型を指定します。
このようなデータの種類をデータ型といいます。
代表的なデータ型には、以下のようなものがあります。
| データ型 | 説明 |
|---|---|
number |
数値 |
string |
文字列 |
boolean |
真偽値 |
any |
任意の型 |
string型
例えば、以下のように記述します。
let data: string = "nemlog";
data = "shu";
console.log(data);
この場合、shuと表示されます。
しかし、以下の場合はTypeScriptでエラーになります。
let data: string = "nemlog";
data = 100;
console.log(data);
なぜなら、変数dataにはstring型を指定しているのに、数値である100を代入しているからです。
このように、TypeScriptでは変数のデータ型を指定することで、間違った型の値を代入した場合にエラーとして検出できます。
データ型を省略する
データ型や初期値を以下のように省略して書くこともできます。
let data = "nemlog";
data = "shu";
console.log(data);
この場合、TypeScriptは初期値である"nemlog"から、dataをstring型として推論します。
そのため、以下のコードも問題ありません。
let data = "nemlog";
data = "shu";
console.log(data);
一方で、TypeScriptでは型推論があるため、必ずしもすべての変数に型を明示的に書く必要があるわけではありません。
例えば、
let data = "nemlog";
と書けば、TypeScriptはdataをstring型として扱います。
any型
次のようなコードを考えてみます。
let data;
data = 4;
data = "nemlog";
console.log(data);
この場合、変数dataには数値や文字列などを代入できます。
値の種類を問わず変数に代入したい場合は、any型を使用することもできます。
let data: any = "nemlog";
data = 100;
console.log(data);
ただし、anyを多用するとTypeScriptの型チェックというメリットを活かせなくなります。
そのため、基本的にはanyの使用は必要最小限にした方がよいでしょう。
定数について
一度値を宣言したら、後から別の値を代入できないものを定数といいます。
定数はconstを使って宣言します。
const 定数の名前: データ型 = 初期値;
例えば、
const z: number = 5;
z = 3;
console.log(z);
とした場合、エラーになります。
zにはすでに5という値が入っており、constで宣言された変数には後から別の値を代入できないためです。
関数について
関数とは、ある処理をひとまとめにして書いたものです。
入力された値を引数として受け取り、処理した結果を戻り値として返すことができます。
例えば、ご飯を炊くことに例えると、
- 炊飯前の米 → 引数
- 炊飯器 → 関数
- 炊いたご飯 → 戻り値
と考えることができます。
戻り値はreturn文を使って返します。
基本的には以下のように記述します。
return 値;
または、
return 式;
と記述します。
関数の定義
TypeScriptでは、関数を以下のように定義できます。
function 関数名(
引数: 引数のデータ型
): 戻り値のデータ型 {
処理内容
}
例えば、2つの数値の平均を求める関数は以下のようになります。
function ave(one: number, two: number): number {
return (one + two) / 2;
}
console.log(ave(8, 4));
// 結果:6
oneとtwoはnumber型の引数です。
また、numberを指定することで、この関数がnumber型の値を返すことを示しています。
関数を変数に代入する
関数を変数に代入することもできます。
let ave = function(one: number, two: number): number {
return (one + two) / 2;
};
console.log(ave(8, 4));
// 結果:6
この場合、aveという変数に関数を代入しています。
アロー関数
アロー記号=>を使って、関数を記述することもできます。
let ave = (one: number, two: number): number => {
return (one + two) / 2;
};
console.log(ave(8, 4));
// 結果:6
このような関数をアロー関数といいます。
JavaScriptやTypeScriptでは、アロー関数がよく利用されます。
関数の型を指定する
関数そのものに型を指定することもできます。
let ave: (one: number, two: number) => number =
function(one: number, two: number): number {
return (one + two) / 2;
};
console.log(ave(8, 4));
// 結果:6
この場合、
(one: number, two: number) => number
によって、
-
number型の引数を2つ受け取る -
number型の値を返す
という関数の型を指定しています。
配列について
プログラミングコードを書く際、変数をいくつも定義すると、コードが複雑になることがあります。
そのときに役に立つのが配列です。
配列は、複数の値をまとめて保管できる変数です。
ここで定義した変数を配列名といい、配列の中に入っている値を要素といいます。
① 配列
配列は以下のように記述できます。
let 配列名: 要素のデータ型[] = 初期値;
例えば、
let data: string[] = [
"jaguar",
"gimre",
"hatchet",
"broodierookie"
];
と記述できます。
この場合、dataという配列の中に4つの文字列が入っています。
インデックス番号
配列にはインデックス番号が割り振られています。
インデックス番号は先頭から、
0
1
2
3
というように、0から始まります。
配列から特定の値を取り出す場合は、以下のように記述します。
配列名[インデックス番号];
先ほどの配列からhatchetを表示したい場合は、
console.log(data[2]);
とします。
実際に書くと以下のようになります。
let data: string[] = [
"jaguar",
"gimre",
"hatchet",
"broodierookie"
];
console.log(data[2]);
結果は、
hatchet
となります。
② オブジェクト
文字列のキーと値を組み合わせてデータを管理する場合は、オブジェクトを利用できます。
例えば、以下のように記述できます。
let arr: { [index: string]: string } = {
"NEM": "ネム",
"SYMBOL": "シンボル",
"Catapult": "カタパルト"
};
console.log(arr.NEM);
// 結果:ネム
このように、キーと値を組み合わせてデータを管理できます。
値を取り出す場合は、
オブジェクト名.キー
と記述します。
③ 列挙型
複数の定数をまとめて扱う場合には、**列挙型(enum)**を利用できます。
基本的な書式は以下のようになります。
enum 列挙型の名前 {
定数,
...
}
例えば、
enum xymcity {
Jag = 8,
Gim = 10,
Hat = 2
}
let ing: xymcity = xymcity.Jag;
console.log(ing);
// 結果:8
このように、enumを使うことで関連する定数をまとめて管理できます。
④ タプル型
タプルとは、複数の異なるデータ型を決められた順番で扱うためのデータ型です。
基本的には以下のように記述します。
let 変数名: [データ型1, データ型2, ...] = [
値1,
値2,
...
];
例えば、
let data: [string, number, number] = [
"apple",
10,
20
];
console.log(data[0]);
// 結果:apple
console.log(data[1]);
// 結果:10
console.log(data[2]);
// 結果:20
この例では、
[string, number, number]
と指定しているため、
- 1番目 →
string - 2番目 →
number - 3番目 →
number
という型になります。
オブジェクト指向について
クラスについて
クラスとは、名前や属性といった情報(プロパティ)や、プログラミング処理(メソッド)をひとつにまとめたものです。
クラスは以下のように定義します。
class クラス名 {
プロパティ名: プロパティのデータ型;
constructor(引数: データ型, ...) {
処理内容
}
メソッド名(
引数: データ型,
...
): 戻り値のデータ型 {
処理内容
}
}
例
class SmallAnimal {
// プロパティ
animalType: string;
// コンストラクタ
constructor() {
this.animalType = "ポメラニアン";
}
say() {
console.log(
`${this.animalType}だけどMSの中に永らく居たBOM信者の全身の毛をむしりたい`
);
}
}
const smallAnimal = new SmallAnimal();
smallAnimal.say();
// ポメラニアンだけどMSの中に永らく居たBOM信者の全身の毛をむしりたい
この例では、SmallAnimalというクラスを作成しています。
クラスの中には、
-
animalTypeというプロパティ -
constructorというコンストラクタ -
say()というメソッド
があります。
new SmallAnimal()とすることで、SmallAnimalクラスからインスタンスを作成しています。
なお、この例は以下のページを参考にしています。
アクセス制限について
クラス内のプロパティやメソッドには、アクセスできる範囲を制限することができます。
これらをアクセス修飾子といいます。
代表的なものには、以下があります。
| アクセス修飾子 | 説明 |
|---|---|
public |
クラスの外からもアクセスできる |
protected |
定義したクラスと、その子クラスからアクセスできる |
private |
定義したクラスの内部からのみアクセスできる |
privateの例
class Person {
// nameとageプロパティ
private name: string;
private age: number;
// コンストラクタ
constructor(name: string, age: number) {
this.name = name;
this.age = age;
}
// publicは省略可能
public show(): string {
return `${this.name}は${this.age}歳です。`;
}
}
let p = new Person("田中邦夫", 64);
console.log(p.show());
// 結果:田中邦夫は64歳です。
console.log(p.name);
// エラー:privateなのでクラスの外からアクセスできない
nameとageにはprivateを指定しています。
そのため、クラスの外側から直接アクセスすることはできません。
一方、show()メソッドはpublicなので、クラスの外側から呼び出すことができます。
このように、アクセス修飾子を利用することで、クラス内部のデータをどこから操作できるのかを制御できます。
参考:
Yoshihiro Yamada. 『Quick Master TypeScript Second Edition Sokushu(Japanese Edition)』WingsProject. Kindle版.
最後に
ここまで、TypeScriptを学ぶにあたって基本的なことを書きました。
実際には、この記事に書いていることだけでは本格的なアプリケーション開発はできません。
TypeScriptには、このほかにもジェネリクス、インターフェース、ユニオン型、型エイリアス、名前空間など、さまざまな機能があります。
自分もまだ学習し始めたばかりなので、わからないことも多くあります。
この記事をきっかけに、TypeScriptについて学習していただけたらと思います。
もっと学びたい方は、以下の書籍も参考になります。
『速習 TypeScript 第2版 速習シリーズ』山田祥寛