TypeScriptの勉強 2 ~型について~
初めに
この記事は、「TypeScript の勉強 1 ~導入から実行まで~」の続きです。
一つ前の記事はこちらを参照してください。
実行環境
今回は、tsc
コマンドを用いて TypeScript をコンパイルします。
tsc
コマンドを用いるためには、typescript
をグローバルにインストールする必要があります。
npm install typescript --save -g
tsc
コマンドのオプションは以下のリンクを参照してください。
実行するには以下のようにコマンドを入力します。
tsc --build
node ./dist/index.js
型宣言
TypeScript で型を指定して変数を宣言する場合は、宣言する変数の後に:number
などを指定します。
let num: number = 123;
let str: string = "hoge";
let bool: boolean = true;
TypeScript には、型推定があるため、毎回型を指定する必要はありません。
let num = 123;
console.log(typeof num);
// > number
関数の引数の型指定
TypeScript で関数を宣言する場合、明示的に引数の型を指定(型アノテーション)する必要があります。
function sum(x: number, y: number) {
return x + y;
}
引数の型を指定する理由は、不正な入力によるエラーを防ぐためです。
以下の JavaScript コードは、2 つの引数を合計した値を返す関数を宣言しています。
// 一般的な JavaScript コード
function sum(x, y) {
return x + y;
}
このsum
関数の想定している引数の型は、明らかにnumber
型です。
しかし、JavaScript の仕様では、片方にstring
型を指定すると、その+
演算子が文字列合成として機能します。そのため、戻り値の型が想定していた型と違っていたり、場合によってはNaN
(数値ではない)が返されるなど、意図しないエラーが発生する要因となります。
sum(1, 2);
// > 3
sum(1, "hoge");
// > 1hoge
型一覧
型 | 説明 |
---|---|
any |
型が分からない場合のデフォルトの型 出来るだけ避けるべき型(最終手段) |
unknown |
型が分からない場合にany の代わりに使うべき型 その型が判明するまで unknown の型の値は使用できない |
boolean |
true とfalse の 2 つの値をもつ真偽値型 let a = true のように、一般的には型推定をさせる |
number |
整数や浮動小数点数、整数などの全ての数値の集まりの型 基本的には型推定させる |
bigint |
number 型では扱えないような大きな整数を扱える整数の型 number とbigint の型は違う |
string |
全ての文字列の集まりの型 基本的には型推定させる |
symbol |
ユニークなキーや ID として機能する特殊な値の型 出来ることは多くない |
object |
オブジェクトの型 オブジェクトの形状を指定する |
unknown
型の例
let a: unknown = 10;
// 型が判明していないため使えない
a === "123"; // false
let b = a + 100; // Object is of type 'unknown'.
// 型が判明しているため使える
if (typeof a === "number") {
let c = a + 100; // 110
}
object
型の例
以下のような TypeScript のオブジェクト宣言では、プロパティを認識しません。
let obj: object = {
a: 10,
};
obj.a; // プロパティ 'a' は型 'object' に存在しません。
TypeScript でオブジェクトを宣言する場合は、以下のように記述します。
// 型推定させる
let obj1 = {
a: 10,
};
// 明示的に指定する
let obj2: { a: string } = {
a: "foobar",
};
class
の場合
Class のインスタンスでも同様に記述します。
class Person {
// public は this.first = first の略
constructor(public first: string, public last: string) {}
}
let p: { first: string; last: string } = {
first: "田中",
last: "太郎",
};
// > { first: '田中', last: '太郎' }
プロパティを省略した場合
以下のように、空のオブジェクトやプロパティを省略した場合は、エラーが発生します。
let obj: { a: number };
obj = {};
// プロパティ 'a' は型 '{}' にありませんが、型 '{ a: number; }' では必須です。
?
, key
, readonly
)
プロパティのオプション(TypeScript では、指定されたプロパティのみが存在することを強制しており、プロパティが欠けた場合でもエラーが出ます。
しかし、省略可能なプロパティであることや予定よりも多くのプロパティが存在する場合は、別の記述で対処できます。
let obj: {
a: number;
b?: string;
[key: number]: boolean;
};
obj = {
a: 10,
1: true,
10: false,
};
// > { '1': true, '10': false, a: 10 }
記述 | 説明 |
---|---|
a: number |
obj は、number 型のa を持つこのプロパティが undefined だとエラーを出す |
b?: string |
プロパティ名の後に? を付けるobj がstring 型のb を持つ可能性があり、b を設定する際にundefined でも問題ない |
[key: number]: boolean |
obj は、boolean 型である複数のプロパティを任意の数だけ持つことが出来る |
また、readonly
修飾子で読み取り専用にすることが出来ます。
let obj: {
readonly a: number;
} = {
a: 10,
};
obj.a; // 10
obj.a = 1; // 読み取り専用プロパティであるため、'a' に代入することはできません。
型エイリアス(type)
TypeScript では変数と同様に、今まで指定したような型を指し示す型エイリアスを宣言することが出来ます。
type
を用いて型を宣言します。
type Age = number;
type Person = {
name: string;
age: Age;
};
// Person の型として宣言できる
let obj: Person = {
name: "田中",
age: 20,
};
合併型と交差型
例えば、以下の 2 つのクラスがあるとします。
type Cat = { name: string; purrs: boolean };
type Dog = { name: string; barks: boolean };
合併型
合併型は、2 つのクラスのどちらか、またはその両方の型を持つことを意味します。
type CatOrDogOrBoth = Cat | Dog;
// ネコの場合
let cat: CatOrDogOrBoth = {
name: "Tama",
purrs: true,
};
// イヌの場合
let dog: CatOrDogOrBoth = {
name: "Pochi",
barks: true,
};
// 両方の場合
let both: CatOrDogOrBoth = {
name: "Tama Pochi",
purrs: true,
barks: false,
};
合併型はよく用いられており、例としては関数の戻り値が挙げられます。
以下の関数は、戻り値がstring
とnull
の 2 つとなっており、表現としては合併のstring | null
となります
function myFunc(x: boolean) {
if (x) {
return "OK";
}
return null;
}
// string | null
交差型
交差型は、2 つのクラスの両方の型を備えることを意味します。
type CatAndDog = Cat & Dog;
let both: CatAndDog = {
name: "Tama",
purrs: true,
barks: false,
};
終わりに
- 次の記事
Discussion