TypeScriptには、JavaScriptに備わるデータ型だけでなく、ECMAScript 2015の仕様も採り入れて、型や機能が加えられています。それらを試してみましょう。なお、TypeScriptの型づけの基本については、「TypeScript: 基本型」をお読みください。
01 カラー整数値からRGBカラー成分値を配列で返す関数
以下のコード001(TypeScriptサイトのPlaygroundにリンクしています)は、引数に渡したRGBカラーの整数値からRGBごとの成分値を配列で返す関数です。関数は、つぎのように試すことができます。なお、カラー整数値からRGBカラー成分値を求めるビット演算については、「2進数・16進数とビット演算」05「カラー値とビット演算」をお読みください。
let components: number[] = getColorComponents(0xFFCC99);
console.log(components); // [ 255, 204, 153 ]
console.log(components[0].toString(16), components[1].toString(16), components[2].toString(16));
// ff cc 99
コード001
function getColorComponents(color: number): number[] {
let red : number = color >> 16;
let green: number = color >> 8 & 0xFF;
let blue: number = color & 0xFF;
return [red, green, blue];
}
02 戻り値を配列とオブジェクトから選べるようにする
戻り値をオブジェクトで受け取ることもできるようにします。配列かオブジェクトかは、つぎのように関数にブーリアン(論理)値の第2引数を加えて選びます。戻り値がひとつの型に定まりませんので、以下のコード002はとりあえずany
で型づけしました。
let components = getColorComponents(0xFFCC99, false);
console.log(components); // { red: 255, green: 204, blue: 153 }
コード002
function getColorComponents(color: number, array: boolean): any {
let red : number = color >> 16;
let green: number = color >> 8 & 0xFF;
let blue: number = color & 0xFF;
if (array) {
return [red, green, blue];
} else {
return {red: red, green: green, blue: blue};
}
}
03 戻り値に納める値もふたつ選べるようにする
カラー値を16進数表記で知りたい場合もあります。数値では表せませんので、文字列を用いることにします。そのため、関数にブーリアン値の第3引数を加えます。以下のコード003はUnion型|
により、変数に数値(number
)か文字(string
)という型づけをしました。
let components = getColorComponents(0xFFCC99, false, true);
console.log(components); // { red: 'ff', green: 'cc', blue: '99' }
コード003
function getColorComponents(color: number, array: boolean, string: boolean): any {
let red : number | string = color >> 16;
let green: number | string = color >> 8 & 0xFF;
let blue: number | string = color & 0xFF;
if (string) {
red = red.toString(16);
green = green.toString(16);
blue = blue.toString(16);
}
if (array) {
return [red, green, blue];
} else {
return {red: red, green: green, blue: blue};
}
}
04 オブジェクトを型づけする
関数の戻り値も、any
を改めて、きちんと型づけしましょう。オブジェクトは型をObject
にしたのでは、クラスに定義済みでないプロパティが加えられません。そこで、以下のコード004は、関数の戻り値の型づけにオブジェクト型リテラル(「TypeScript入門 04: オブジェクト型リテラルとインタフェースを使う」02「型定義をつくる」参照)を使いました。なお、配列要素にUnion型を用いるときは、要素の型を丸かっこ()
でくくります。
コード004
function getColorComponents(color: number, array: boolean, string: boolean):
(number | string)[] |
{red: number | string, green: number | string, blue: number | string}
{
let red : number | string = color >> 16;
let green: number | string = color >> 8 & 0xFF;
let blue: number | string = color & 0xFF;
if (string) {
red = red.toString(16);
green = green.toString(16);
blue = blue.toString(16);
}
if (array) {
return [red, green, blue];
} else {
return {red: red, green: green, blue: blue};
}
}
05 引数を配列でまとめる
関数に渡すブーリアン値の引数は、あとあとオプションの数が増える場合に備えて、まとめてしまいます。以下のコード005は、引数をブーリアン値の配列にしました。これなら、手直しもさほど多くありません。
let components = getColorComponents(0xFFCC99, [false, true]);
console.log(components);
コード005
function getColorComponents(color: number, format: boolean[]):
(number | string)[] |
{red: number | string, green: number | string, blue: number | string}
{
let red : number | string = color >> 16;
let green: number | string = color >> 8 & 0xFF;
let blue: number | string = color & 0xFF;
if (format[1]) {
red = red.toString(16);
green = green.toString(16);
blue = blue.toString(16);
}
if (format[0]) {
return [red, green, blue];
} else {
return {red: red, green: green, blue: blue};
}
}
06 複数のフラグを列挙型でまとめる
配列でまとめるとコードは簡単なものの、どの要素が何を決めるのかわかりにくくなります。列挙型enum
を使うと、数値が名前で表せます。そして、ビット演算を用いれば、複数のフラグがひとつの整数で表せるのです(「2進数・16進数とビット演算」02「複数のフラグをひとつの整数で表す」)。以下のコード006は、列挙型とビット演算を使って書き替えました。
console.log(getColorComponents(0xFFCC99)); // { red: 255, green: 204, blue: 153 }
console.log(getColorComponents(0xFFCC99, Format.STRING)); // { red: 'ff', green: 'cc', blue: '99' }
console.log(getColorComponents(0xFFCC99, Format.ARRAY | Format.STRING)); // [ 'ff', 'cc', '99' ]
コード006
enum Format {ARRAY = 1, STRING = 2};
console.log(Format); // { '1': 'ARRAY', '2': 'STRING', ARRAY: 1, STRING: 2 }
function getColorComponents(color: number, format = 0):
(number | string)[] |
{red: number | string, green: number | string, blue: number | string}
{
let red : number | string = color >> 16;
let green: number | string = color >> 8 & 0xFF;
let blue: number | string = color & 0xFF;
if ((format & 2) === Format.STRING) {
red = red.toString(16);
green = green.toString(16);
blue = blue.toString(16);
}
if ((format & 1) === Format.ARRAY) {
return [red, green, blue];
} else {
return {red: red, green: green, blue: blue};
}
}
07 Union型に名前をつける
前掲コード006では、数値(number
)か文字(string
)という型づけがあちこちで使われています。型の別名(type alias)を用いると、ひとつの名前でまとめてしまえます。以下のコード007のようにわかりやすい名前にすれば、スクリプトも見やすくなります。なお、配列はジェネリック型で定めました(別の書き方を示しただけですので、とくに大きな違いはありません)。
コード007
enum Format {ARRAY = 1, STRING = 2};
type NumberOrString = number | string;
console.log(Format); // { '1': 'ARRAY', '2': 'STRING', ARRAY: 1, STRING: 2 }
function getColorComponents(color: number, format = 0):
Array<NumberOrString> |
{red: NumberOrString, green: NumberOrString, blue: NumberOrString}
{
let red : NumberOrString = color >> 16;
let green: NumberOrString = color >> 8 & 0xFF;
let blue: NumberOrString = color & 0xFF;
if ((format & 2) === Format.STRING) {
red = red.toString(16);
green = green.toString(16);
blue = blue.toString(16);
}
if ((format & 1) === Format.ARRAY) {
return [red, green, blue];
} else {
return {red: red, green: green, blue: blue};
}
}