HTML5テクニカルノート
TypeScript: 基本型
- ID: FN1701009
- Technique: HTML5 / JavaScript
- Package: TypeScript 2.1
TypeScript公式Handbook「Basic Types」をもとにした解説です。TypeScriptで用いられる基本的なデータ型についてご説明します。JavaScriptに備わるデータ型だけでなく、TypeScriptがECMAScript 2015の仕様も採り入れて、加えた型や機能もあります。
01 ブーリアン(論理)型
true
(真)かfalse
(偽)の二値どちらかをとるのがboolean
(論理)型です。JavaScriptにも備わっています。値をtypeof
演算子で調べると、"boolean"が返ります。
let isDone: boolean = false; console.log(typeof isDone); // boolean
02 数値型
JavaScriptと同じく、TypeScriptもすべての数値を浮動小数値として扱います。データ型はnumber
です。typeof
演算子は"number"を返します。JavaScriptが扱う10進数と16進数に加えて、TypeScriptではECMAScript 2015 (ES6)で採り入れられた2進数および8進数も使えます。数値の頭に2進数は0b、8進数は0oを添えます(MDN「字句文法」の「Numeric リテラル」参照)。
let decimal: number = 27; let hex: number = 0x1b; let binary: number = 0b11011; let octal: number = 0o33; console.log(decimal, hex, binary, octal); // 27 27 27 27
03 文字列型
テキストなどの文字列データは、string
で型づけします。typeof
演算子の戻り値は"string"です。JavaScriptと同じく、値はダブルクォート("
)またはシングルクォート('
)の引用符でくくります。文字列にクォーテーション記号そのものを含めたいときは、もう一方の引用符を用いればよいでしょう。
let pen: string = "I have a pen."; let apple: string = 'I have an "apple".';
TypeScriptには、ECMAScript 2015のテンプレート文字列も採り入れられました。クォーテーションの替わりにバックティック(`)でくくることで、値の中で改行や文字列内挿機能(${}
)が使えます。
let today: Date = new Date(); let days: string[] = ['日', '月', '火', '水', '木', '金', '土']; let dayOfWeek: string = `本日の曜日: ${days[today.getDay()]}曜日` console.log(dayOfWeek); /* 今日が金曜日であれば 本日の曜日: 金曜日*/
もちろん、つぎのように書くこともできます。コンパイルされたコードは、ほぼこのかたちです。
let dayOfWeek = '本日の曜日:\n' + days[today.getDay()] + '曜日';
04 配列
配列はArray
クラスのインスタンスです。typeof
演算子からは"object"が返されます。配列のデータ型は、要素の型を添えて定めます。構文はふたつあり、ひとつはつぎのように要素の型に角かっこ[]
を加えます。
let list: number[] = [1, 2, 3];
もうひとつは、Arrayクラスをジェネリックで型づけする書き方です。山かっこ<>
の中に要素の型を与えます。
let list: Array<number> = [1, 2, 3];
JavaScriptと同じように要素の型を問わない場合には、any
で型づけすればよいでしょう。
let list: any[] = [1, 'b', new Date()];
要素のデータが任意ではなく、複数の型を与えたいなら、Union型が使えます。[]
の構文の場合は、要素の型は丸かっこ()
でくくってください。
let list: (number | string)[] = [1, 'b', 3];
ジェネリック型の書き方では、山かっこ<>
の要素の型づけにUnion型を用います。
let list: Array<number | string> = [1, 'b', 3];
05 タプル型
タプル型は、配列に要素ごとの型を定めます。配列に、決められた型で要素が納められていないとエラーになります。要素の値を書き替えるときも、決められた型のデータでなければなりません。
let list: [number, string]; list = [1, 'b']; // list = ['1', 'b']; // 要素の型が違うのでエラー // list = [1]; // 要素が足りないのでエラー
新たな要素を加えることはできます。ただし、その型はタプルに与えた型のいずれかでなければなりません。
list = [1, 'b', 3]; // list = [1, 'b', new Date()]; // タプルにDate型が与えられていないのでエラー
要素を取り出してプロパティやメソッドを参照するときは、その要素の型ごとに評価されます。したがって、ひとつの要素で参照できたプロパティやメソッドも、他の型の要素で使おうとすればエラーになる場合があります。
console.log(list[0].toString(2)); // インデックスが1だとエラー console.log(list[1].length); // インデックスが0だとエラー
06 列挙型
列挙型enum
は、数値に識別子を与えます。デフォルトでは、数値は0から始まる連番整数です。数値が名前で扱え、enum
で型づけすれば使われる数値もはっきりします[*1]。
enum Index {zero, one, two}; console.log(Index); // { '0': 'zero', '1': 'one', '2': 'two', zero: 0, one: 1, two: 2 } let id: Index = Index.one;
識別子に与える数値は、代入のかたちで変えられます。そのあとの値を与えられていない識別子は、その値からの連番整数になります。
enum Index {zero, one = 11, two}; console.log(Index); // { '0': 'zero', '11': 'one', '12': 'two', zero: 0, one: 11, two: 12 }
enum
は識別子で数値を定めるだけではありません。数値から識別子を調べることもできます。
enum Color {red = 0xFF0000, green = 0xFF00, blue = 0xFF}; let color: Color = Color.blue; let colorName: string = Color[color]; console.log(color, colorName); // 255 'blue'
enum
で型づけしても、与える数値そのものは縛れません。
enum Index {zero, one, two}; let id: Index = 100; // エラーにならない console.log(id); // 100
07 any型
データ型を予め決められないときは、any
型が使えます。たとえば、ユーザーやサードパーティのライブラリで、値が動的に与えられる場合などです。前述の要素の型を問わない配列に用いる場合もありました。any
で型づけされたデータは、コンパイルするとき型にもとづくチェックが省かれます。
let list: any[] = [1, 'b', new Date()];
Object
クラスで型づけした変数には、任意のプロパティを加えたオブジェクトが代入できます。けれど、その値を調べようとすると、エラーになってしまいます。Object
クラスに定義済みでないプロパティは参照できないのです。
let object: Object = { prop: 1 }; // console.log(object.prop); // Objectクラスに定義されていないプロパティなのでエラー
変数をany
で型づけすれば、どのようなプロパティやメソッドを加えても参照できます。ただし、プロパティのデータ型はもちろん、その存在さえ確かめられなくなることにご注意ください。
let object: any = { prop: 1 }; console.log(object.prop); // 1 console.log(object.prop.length); // undefined console.log(object.nothing); // undefined
オブジェクトに加えるプロパティとデータ型が決まっているときは、オブジェクト型リテラルあるいはインタフェースを使うのがよいでしょう。
let object: {prop: number} = { prop: 1, }; console.log(object.prop); // 1 console.log(object.prop.toString(2)); // 1 // console.log(object.prop.length); // データ型に備わっていないのでエラー // console.log(object.nothing); // 型づけに与えられていないのでエラー
08 void型
void
型は値がないことを示します。おもに用いられるのは、関数の戻り値の型づけでしょう。
function warn(): void { alert('warning'); }
変数に使えないわけではありません。ただ、値として納められるのはundefined
かnull
だけです。実際に用いられることは、ほとんどないでしょう。
let unusable: void = undefined;
09 undefined型とnull型
値undefined
とnull
には、それぞれundefined
およびnull
という型が定められています。けれど、これらの型づけを単独で用いることはなさそうです。
let _undefined: undefined = undefined; let _null: null = null;
TypeScript 2.0から--strictNullChecks
のモードが備わりました。このモードではnull
とundefined
は、それぞれの型とvoid
の型づけでしか値が受け取れません。データがより厳しく扱えるので、TypeScriptは--strictNullChecks
モードを推奨しています。けれど、値がなくても一旦受け取り、その判定をしたうえで、処理は進めたい場合もあるでしょう。そのようなときは、undefined
とnull
をUnion型で用います。
let text: string | undefined | null;
10 never型
決して起こらないのがnever
型です。関数が正しく終わらなければ、値は返せません。必ずエラーになる関数の戻り値は、never
型になります。void
でも型づけは可能です。正しく終わらないことを明らかにするための型といえます。
function error(message: string): never { throw new Error(message); } function fail(): never { return error("failed"); } function infiniteLoop(): never { while (true) {} }
変数をnever
で型づけることもできます。このとき、代入できるのはnever
型の値だけです。
let neverDone: never = (() => { throw new Error('failed') })();
11 型変換
ある型のデータを別の型で指定し、評価し直します。型アサーション(type assertion)あるいはキャストと呼ばれる機能です。ただし、TypeScriptがとくにデータをチェックしたり、構築し直すことはありません。実行時の負荷にはならないということです。
ふたつの構文があり、ひとつは山かっこ<>
を用います。
let someValue: any = 'this is a string'; let length: number = (<string>someValue).length;
もうひとつは、as
構文です。どちらの構文でも、処理の中身は変わりません。ただし、JSXを使うときは、as
のみ許されます。
let someValue: any = 'this is a string'; let length: number = (someValue as string).length;
12 letキーワードについて
TypeScriptでは変数をJavaScriptと同じvar
で宣言することもできます。けれど、TypeScriptでは、できるだけlet
宣言を使うことが推奨されています。キーワードvar
とlet
の違いについては、「TypeScript入門 07: ブロックスコープに変数を宣言する ー let」をお読みください。
13 型づけを使ったコード例
Qiita「TypeScriptの型づけを使う ー Union型、列挙型、型の別名など」は、ここまで解説したいくつかの型を用いたコード例です。ビット演算の応用も交えてご紹介しています。
作成者: 野中文雄
更新日: 2017年2月13日 13「型づけを使ったコード例」を追加。
作成日: 2017年1月27日
Copyright © 2001-2017 Fumio Nonaka. All rights reserved.