TypeScriptの勉強 3 ~配列、タプル、enum、関数~


初めに

この記事は、「TypeScript の勉強 2 ~型について~」の続きです。

一つ前の記事はこちらを参照してください。

https://zenn.dev/masa_dev/articles/5d763744d5fc4c361c5e

配列

配列を宣言する場合は基本的に型推定させます。

配列は、以下のような書き方が出来ます。

let a = [1, 2, 3];            // number[]
let b = ["A", 1];             // (string | number)[]
let c: number[] = [1, 2, 3];  // number[]
let d: boolean[] = [];

d.push(true);                 // d = [true]

タプル

タプルは配列の派生形の 1 つであり、固定長の配列を型付けするための方法です。

指定した配列の長さを持った配列のような物です。配列の型アノテーションが : any[] のような形であるのにたいして、タプルは: [any]の形を取ります。

let a: [boolean] = [true];
let b: [string, number] = ["ABC", 123];

// 以下のような場合はエラーが出る
let c: [number, number, string] = [1, 2];
  // Type '[number, number]' is not assignable to type '[number, number, string]'.

また、?やスプレット構文(...)等を用いて可変長のタプルを生成できます。

// d と e は同じ
let d: [number, string?] = [1];             // 2つ目の要素は無くてもいい
let e: ([number] | [number, string]) = [1];

// スプレッドする型は配列にする
let f: [boolean, ...number[]];
f = [true, 1, 2, 3, 4, 5];                 // [ true, 1, 2, 3, 4, 5 ]

型列挙(enum

型列挙は、ある方について取り得る値を列挙する(enumerate)方法です。

enum Language {
  English,
  Spanish,
  Russian
}
/* {
  '0': 'English',
  '1': 'Spanish',
  '2': 'Russian',
  English: 0,
  Spanish: 1,
  Russian: 2
} */

また、任意の値を指定することもできます。

enum Color {
  Red = "#c10000",
  Blue = 0x007ac1,  // 16進数
  White = 255,
  Next
}

Color.Red;  // #c10000
Color[255]; // White

// 自動的に番号が振られる
Color.Next; // 256

関数

関数は基本的に JavaScript と同じ書き方が出来ますが、パラメータを明示的にアノテートする必要があります。

以下の例では、引数パラメータのxyは型が不明なため型アノテーションが必要になります。戻り値は、TypeScript が型推定できるため、指定していません。

function add(x: number, y: number) {
  return x, y;
}

戻り値も含めて明示的にアノテートする場合は以下の通りです。

function add(x: number, y: number): number {
  return x, y;
}

パラメーターは省略可能にすることが出来ます。

// ? でパラメータ省略可能
function log(message: string, userId?: string) {
  console.log(message, userId || "Not signed in");
}

スプレット構文も使えます。

function sum(x: number, ...y: number[]) {
  let sum = x;
  y.forEach((item) => sum += item);

  return sum;
}

ジェネレータ

ジェネレータは、一連の値を生成するための方法です。ジェネレータは利用者が呼び出した時に次の値を計算します。

ジェネレータの宣言方法はfunctionの後に*(アスタリスク)を付けるだけです。

function* createFibonacciGenerator() {
  let a = 0;
  let b = 1;
  while (true) {
    yield a;
    [a, b] = [b, a + b];
  }
}

let createFibonacci = createFibonacciGenerator();
createFibonacci.next(); // { value: 0, done: false }
createFibonacci.next(); // { value: 1, done: false }
createFibonacci.next(); // { value: 1, done: false }
createFibonacci.next(); // { value: 2, done: false }
createFibonacci.next(); // { value: 3, done: false }
createFibonacci.next(); // { value: 5, done: false }

ユーザーがnextメソッドを実行すると、次の値を出力し、実行を休止します。つまり、ユーザーが呼び出すまで一時停止します。

ジェネレータが返す値は、yieldキーワードによって返されます。

また、ジェネレータが返す値はTypeScriptが型推定していますが、明示的にアノテートすることが出来ます。

function* createFibonacciGenerator(): Generator<number> {
  let a = 0;
  let b = 1;
  while (true) {
    yield a;
    [a, b] = [b, a + b];
  }
}

呼び出しシグネチャ

関数の型に使われる書き方を呼び出しシグネチャといいます。

以下のような書き方をします。形はアロー関数に似ています。

// こんなやつ
(a: number, b: number) => number

主に型エイリアスの宣言で使われます。

// 関数の型宣言
type Add = (a: number, b: number) => number;

// Add型を用いた関数宣言
let add: Add = (a, b) => {
  return a + b;
}

終わりに

学習することが多くて、大変です。

あと、基本的に動作チェックはしていますが、間違ってたらすみません ^^。