はじめに
本記事では「プログラミング TypeScript ―スケールする JavaScript アプリケーション開発」について自身の学習も含めて、数回に渡って紹介しています。
プログラミングTypeScript ―スケールするJavaScriptアプリケーション開発
- 作者:Boris Cherny
- 発売日: 2020/03/16
- メディア: 単行本(ソフトカバー)
前回は、プログラミング TypeScript:第 2 章 TypeScript 全体像について紹介しました。
今回は、第 3 章の型について紹介していきます。
また、学習用にサンプルプログラミングも Github で紹介していますので、合わせて紹介しています。 github.com
型について
実は、前回の章でも型システムの概念は紹介していましたが、型システムにおける「型」が実際に何を意味するのかを定義していませんでした。
型 (type) :値と、それを使ってできる事柄の集まり
これだと理解しづらいかもしれないので、例をいくつか挙げます。
- boolean 型は、すべてのブール値 (true と false の2つだけです)と、それらについて行うことのできる演算や操作 (||、&&、!など)の集まりです。
- number 型は、すべての数値と、それらについて行うことのできる演算や操作 (+、-、*、/、%、||、&&、?など)の集まりです。これには、.to.Fixed、.toPrecision、.toString など、それらについて呼び出すことのできるメソッドも含まれます。
- string 型は、すべての文字列と、それらについて行うことのできる演算や操作 (+、||、&& など) の集まりです。これには、.concat や .toUpperCase など、それらについて呼び出すことのできるメソッドも含まれます。
あるものの型が T であることを目にした場合、単にそれが T であることが分かるだけでなく、その T を使って「具体的に何ができるのか」(および何ができないのか)が分かるのです。肝心なのは、型チェッカーを使って、不正なことをしてしまうのを防ぐことです。そして型チェッカーが、何が正しくて何が正しくないかを知る方法、あなたが使っている型と、それらをあなたがどのように使っているかを調べることです。
以下の図は、TypeScript の型の概観を示しています。図が示すように多くの型を使用することができます。
ここでは、型の詳細については他のWebサイトなどを参照していただき、練習問題を中心に紹介しています。
各型の詳細については、以下のサイト等をご参照ください。
js.studio-kingdom.com
github.com
TypeScript にプログラムの値から型を推論させることができますし、プログラマーが値を明示的に型付けすることもできます。const を使うと、TypeScript はより具体的な型を推論し、let や var を使うと、より一般的な型を推論します。多くの型には、より一般的なものと、それに対応するより具体的な物があり、後者は前者のサブタイプです。
表 さまざまな型とそれらのより具体的なサブタイプ
型 | サブタイプ |
---|---|
boolean | 真偽値リテラル |
bigint | BigInt リテラル |
number | 数値リテラル |
string | 文字列リテラル |
symbol | unique symbol |
object | オブジェクトリテラル |
配列 | タプル |
enum | const enum |
練習問題
- 次のそれぞれの値について、TypeScript はどのような型を推論するでしょうか?
// a let a = 1042 // number // b let b = 'apples and oranges' // string // c const c = 'pineapples' // 'pineapples' // d let d = [true, true, false] // boolean[] // e let e = {type: 'ficus'} // {type: string} // f let f = [1, false] // (number | boolean)[] // g const g = [3] // number[] // h let h = null // any
- 次のそれぞれのものは、なぜエラーをスローするのでしょうか?
// a let i: 3 = 3 i = 4 // エラー TS2322: 型 '4' を型 '3' に割り当てることはできません。 /* 回答:iの型はリテラル型の3です。4の型はリテラル型の4であり、これをリテラル型の3に割り当てることはできません。 */ // b let j = [1, 2, 3] j.push(4) j.push('5') // エラー TS2345: 型 '"5"' の引数を型 'number' の // パラメーターに割り当てることはできません。 /* 回答:j は number のセットを使って初期化されたので、TypeScript は j の型を number[] と推論しました。'5' の型はリテラル型の '5' であり、これを number に割り当てることはできません。 */ // c let k: never = 4 // エラー TS2322: 型 '4' を型 'never' に // 割り当てることはできません。 /* 回答:never はボトム型です。つまり、never を他のすべての型に割り当てることはできますが、never にはどの型も割り当てることができません。 */ // d let l: unknown = 4 let m = l * 2 // エラー TS2571: オブジェクトの型は 'unknown' です。 /* unknown は、実行時に何にでもなりうる値を表します。あなたがしていることが安全であることを TypeScript に示すには、まず、unknown型の値が、実際にはより具体的なサブタイプを持っていることを TypeScript に示す必要があります。これを行うには、typeof、instanceof、または他の型クエリーや型ガードを使って値を絞り込みます。 */
さいごに
今回は型を中心でしたが、次は関数です。次回もなるべく要点を絞って紹介していければと思います。