TypeScript での型の概要
TypeScript の主な利点は、静的な型を JavaScript のコードに追加できることです。 型により、関数、変数、プロパティなどのプログラム エンティティに対して静的な制約が設けられ、コンパイラや開発ツールで開発時にいっそう適切な検証と支援を提供できるようになります。
TypeScript の静的なコンパイル時型システムでは、JavaScript の動的な実行時型システムが厳密にモデル化されています。 静的なコンパイル時型システムにより、プログラムの実行時に存在すると予想される型の関係を正確に表現できます。 次に、それらの想定を TypeScript コンパイラで事前に検証することができます。 TypeScript の型分析はコンパイル時に完全に行われるので、実行時のオーバーヘッドがプログラムの実行に加わることはありません。
また、静的型を使用すると、ご自分のコードの意図をより適切に文書化することができ、開発者自身や他の開発者が理解するのに役立ちます。
let 変数と const 変数の宣言
ECMAScript 2015 において、JavaScript の変数宣言に let
キーワードと const
キーワードが追加されました。これにより、以前のバージョンの var
キーワードに関連するいくつかの問題が解消されました。 この変更により、ブロック レベルのスコープで変数を宣言できるようになり、同じ変数を複数回宣言することができなくなります。
TypeScript では、変数の宣言に let
キーワードと const
キーワードを使用することが奨励されています。
Note
両者の違いを確認しておくと、let
宣言は初期化せずに行うことができますが、const
宣言は常に値で初期化されます。 また、const
宣言は、いったん割り当てると、後で割り当て直すことはできません。
演習 - TypeScript での型の推定
型と変数の関連付けは、明示的な型の注釈または暗黙的な型の推定によって行うことができます。
明示的な型の注釈を使用することが推奨されますが、TypeScript では省略可能です。 明示的な型を宣言するには、構文 variableName: type
を使用します。 let myVariable: number
というステートメントを使用すると、初期化されない数値型として変数が宣言されます。 または、let myVariable: number = 10
を使って変数を初期化することもできます。
型の推定を使用して変数の型を暗黙的に示すには、JavaScript で使用するのと同じ形式を使用します。 たとえば、let myVariable = 10
と指定すると、値 10
で初期化されているため、変数は number
型であると推定されます。
プレイグラウンドを開き、どのように動作するか見てみましょう。
次の変数宣言を入力します。
let x: number; //* Explicitly declares x as a number type let y = 1; //* Implicitly declares y as a number type let z; //* Declares z without initializing it
TypeScript により、
x
はnumber
型として処理されるようになります。 また、TypeScript ではy
の型はnumber
型であると推定されます。その初期化にその値の型が使用されているためです。 それでは、異なる値の型をそれに割り当てようとするとどうなるでしょう? そして、変数 z はどうなるのでしょうか?プレイグラウンドの [エラー] タブを開いて、エラーを監視できるようにします。
「
x = 1
」と入力します。 この宣言は、エラーなしで想定どおりに動作するはずです。「
x = "one"
」と入力します。 想定どおり、この宣言では "Type 'string' is not assignable to type 'number'" ('string' 型を 'number' 型に代入することはできません) というエラーが発生します。静的型チェックによりstring
を変数に代入することが許可されないためです。「
y = "one"
」と入力します。 TypeScript によって y がnumber
型であると推定されているため、同じエラーが発生することがわかります。変数名
y
の後にピリオドを入力すると、もう 1 つのことがわかります。 変数y
の型を明示的に指定しなかった場合でも、Intellisense からはnumber
型にのみ適用されるメソッドが示されます。「
z = 1
」および「z = "one"
」と入力します。 どちらも TypeScript によって受け入れられましたが、なぜでしょう。 これらの宣言は、JavaScript の場合と同じように動作します。変数z
に、代入された任意の値を指定できるようになったためです。 型の代入も、宣言時の初期化も行わなかったため、TypeScript によりz
はany
型であると推定されています。any
型については後でさらに詳しく学習します。
TypeScript の型の推定を使用して型を暗黙的に推定することはできますが、そうすべきでしょうか? 型の推定を使用すると、静的型チェックと Intellisense のいくつかの利点を得られ、プロジェクトでは明示的な型宣言に段階的に移行することもできます。 ただし、明示的な型宣言を使用すると、コードの意図をより適切に文書化でき、いっそう計画的に物事を進めることができます。
TypeScript の型とサブタイプ
変数宣言で型を実際に使用する前に、TypeScript での型とサブタイプについて見てみましょう。
任意の型
TypeScript のすべての型は、any
型という名前の 1 つの最上位の型のサブタイプです。 any
型は、制約なしに任意の JavaScript 値を表すことができる 1 つの型です。 他のすべての型は、プリミティブ型、オブジェクト型、または型パラメーターとして分類されます。 これらの型により、それぞれの値に対してさまざまな静的制約が導入されます。
プリミティブ型
プリミティブ型は、boolean
、number
、string
、void
、null
、undefined
の各型と、ユーザー定義の列挙型または enum
型です。 void
型は、戻り値のない関数など、値がないことを示すためにのみ存在します。 null
型と undefined
型は、他のすべての型のサブタイプです。 null
型と undefined
型を明示的に参照することはできません。 リテラル null
および undefined
を使って、これらの型の値のみを参照できます。
オブジェクト型と型パラメーター
オブジェクト型は、すべてのクラス型、インターフェイス型、配列型、およびリテラル型です (プリミティブ型ではないものすべて)。
クラス型とインターフェイス型は、クラスとインターフェイスの宣言を通じて導入され、宣言で指定された名前によって参照されます。 クラス型とインターフェイス型は、1 つ以上の型パラメーターを持つジェネリック型にすることができます。 これらのオブジェクト型については、後のモジュールでさらに学習します。