TypeScriptの最大の特徴は、静的型付けによってコードの安全性と信頼性を高めることができる点です。静的型付けとは、変数や関数の引数、戻り値などに型を指定し、実行時ではなくコンパイル時にエラーを検出できる仕組みです。これにより、予期しないバグや実行時エラーを防ぐことができます。
この章では、TypeScriptにおける基本的な型と、その型を使って型安全なコードを書くための型注釈について詳しく解説します。
3.1 型注釈とは?
型注釈とは、変数や関数などに対して、どのようなデータ型が使われるかを明示的に指定する方法です。JavaScriptは動的型付け言語で、実行時に型が決まりますが、TypeScriptでは変数に型を指定することで、プログラムが予期せぬ動作をしないようにすることができます。
型注釈の基本
型注釈を追加するには、変数や関数の後にコロン(:)をつけ、その後に型名を指定します。
let message: string = "Hello, TypeScript!";
この例では、message
という変数がstring
型であることを指定しています。TypeScriptコンパイラは、この変数に対して文字列以外のデータ型が代入された場合にエラーを表示します。
3.2 基本的な型
TypeScriptには、いくつかの基本的なデータ型が用意されています。ここでは、最もよく使われる基本的な型について説明します。
3.2.1 number
型
number
型は、数値を表す型です。JavaScriptの数値型と同様に、整数や浮動小数点数を扱うことができます。
let age: number = 25;
let price: number = 19.99;
TypeScriptでは、整数も浮動小数点数も区別されず、すべてnumber
型として扱われます。
3.2.2 string
型
string
型は、文字列を表す型です。シングルクォート、ダブルクォート、またはテンプレートリテラル(バッククォート)を使って文字列を指定します。
let firstName: string = "John";
let greeting: string = `Hello, ${firstName}!`;
テンプレートリテラルを使うと、変数や式を文字列内で埋め込むことができ、コードがより直感的になります。
3.2.3 boolean
型
boolean
型は、真偽値(true
またはfalse
)を表します。条件分岐や論理演算などで頻繁に使用されます。
let isLoggedIn: boolean = true;
let hasPaid: boolean = false;
3.2.4 null
と undefined
TypeScriptには、null
と undefined
という特殊な型も存在します。null
は「値が存在しない」ことを表し、undefined
は「未定義」を意味します。
let notAssigned: null = null;
let notDefined: undefined = undefined;
TypeScriptでは、null
と undefined
はそれぞれ独立した型ですが、通常はこれらの値を許容するためにユニオン型として扱うことが多いです(詳細は後述)。
3.3 配列の型
TypeScriptでは、配列の型を指定する方法も簡単です。配列に対して、どの型の要素を含むかを明確に指定できます。
3.3.1 単純な配列
配列の型を指定する方法の一つは、要素の型の後に**[]
**をつける方法です。これにより、その配列には指定した型の要素しか格納できなくなります。
let numbers: number[] = [1, 2, 3, 4, 5];
let names: string[] = ["Alice", "Bob", "Charlie"];
この例では、numbers
配列はnumber
型の要素のみ、names
配列はstring
型の要素のみを含むことができます。異なる型を代入しようとすると、エラーが発生します。
3.3.2 ジェネリックを使った配列
もう一つの配列の型指定方法として、ジェネリック型を使う方法もあります。これは、Array<T>
の形式で書くことで、型T
の要素を含む配列を指定します。
let scores: Array<number> = [90, 85, 100];
let fruits: Array<string> = ["Apple", "Banana", "Cherry"];
この方法は、型注釈としても一般的に使われており、柔軟な型指定が可能です。
3.4 オブジェクトの型
JavaScriptでは、オブジェクトはキーと値のペアの集合体として扱われます。TypeScriptでも同様ですが、オブジェクトの型を定義することで、各プロパティの型を明示的に指定することができます。
let person: {
name: string;
age: number;
isStudent: boolean;
} = {
name: "John",
age: 25,
isStudent: false
};
この例では、person
オブジェクトがname
、age
、isStudent
という3つのプロパティを持ち、それぞれの型が指定されています。オブジェクトの型を明示することで、誤ったデータを格納することを防ぐことができます。
3.5 タプル(Tuple)
タプルは、固定された数の要素を持ち、それぞれの要素に異なる型を指定できる配列のようなものです。JavaScriptには存在しない概念ですが、TypeScriptではこの機能を使って、複数の異なる型を1つの配列にまとめることができます。
let personInfo: [string, number, boolean] = ["Alice", 30, true];
この例では、personInfo
はタプル型であり、最初の要素はstring
型、2番目はnumber
型、3番目はboolean
型であることが指定されています。
3.6 any
型
any
型は、どんな型の値でも許容する特殊な型です。TypeScriptの型システムを無視して、自由にデータを扱いたい場合に使用しますが、できるだけ避けるべきです。なぜなら、any
型を多用すると、型安全性が失われるためです。
let dynamicValue: any = "Hello";
dynamicValue = 42; // 型の変更も許される
dynamicValue = true;
any
型は非常に便利ですが、型のメリットを活かすためには、any
型の使用は必要最小限にとどめるのが望ましいです。
3.7 型推論
TypeScriptでは、変数や関数の型を明示的に指定しなくても、型推論によって自動的に型を決定することができます。これは、変数に初期値を割り当てる際に、その初期値に基づいてTypeScriptが適切な型を推測してくれる機能です。
let autoMessage = "This is a string"; // TypeScriptは自動的にstring型と推論
autoMessage = 123; // エラー: string型にnumber型を代入できない
この例では、autoMessage
変数には明示的な型注釈がありませんが、"This is a string"
という初期値からstring
型であると推論されています。以降、この変数には文字列以外の値を代入することができません。
3.8 ユニオン型
ユニオン型は、複数の型を持つことができる型です。例えば、ある変数がstring
型またはnumber
型である可能性がある場合、ユニオン型を使ってその両方の型を許容することができます。
let id: string | number;
id = 123; // number型として使用
id = "ABC123"; // string型として使用
この例では、id
変数はstring
型またはnumber
型のどちらかの値を取ることができます。ユニオン型は、動的なデータを扱う際に非常に便利です。
型ガード
ユニオン型を使うとき、TypeScriptにどの型が現在使用されているかを明示的に示すために型ガードを使用することがあります。typeof
演算子を使って、現在の型を判定します。
function printId(id: string | number) {
if (typeof id === "string") {
console.log(`ID is a string: ${id}`);
} else {
console.log(`ID is a number: ${id}`);
}
}
このように、ユニオン型を使うと柔軟に型を管理できますが、型ごとの処理を行う場合には型ガードが役立ちます。
まとめ
この章では、TypeScriptにおける基本的な型と型注釈について詳しく説明しました。TypeScriptの静的型付けにより、JavaScriptに比べて型安全なコードを書くことができます。また、配列やオブジェクト、タプル、ユニオン型など、TypeScriptが提供するさまざまな型システムを理解することで、より堅牢で予測可能なコードを書くことができるようになります。