目次

 

1. 概要

このシリーズでは、TypeScriptの入門教材としてサバイバルTypeScriptで学習し、個人的に重要だと思った箇所を備忘録として記事に記載しています。

今回の記事では、第四章 読んで学ぶTypeScriptを題材に、TypeScriptの言語機能詳細について学んでいきます。

 

2. 変数

2.1. 変数宣言の型注釈

以下のように記載することで、変数宣言時の型注釈が行えます。

const num: number = 123;

2.2. 変数を読み取り専用にする(readonlyプロパティ)

2.2.1. 基本的な書き方

TypeScriptでは、オブジェクトを読み取り専用にすることが出来ます。 以下のようにreadonly修飾子をつけることで適用されます。 読み取り専用プロパティに対して値を代入しようとすると、コンパイラが警告してくれます。

let obj: {
  readonly foo: number;
};

2.2.2. readonlyは再帰的ではない

readonlyプロパティは再帰的ではありません。 つまり、下記の例のように、fooにreadonly修飾子が記載されており、foo内部のbarにはreadonly修飾子が記載されていない場合、foo自体への代入はコンパイルエラーになりますが、barへの代入はコンパイルエラーになりません。

let obj: {
  readonly foo: {
    bar: number;
  };
};

2.2.3. 一括して読み取り専用にしたい場合

ユーティリティ型のReadonlyを使い、以下のように記載します。

let obj: Readonly<{
  a: number;
  b: number;
  c: number;
  d: number;
  e: number;
  f: number;
}>;

 

3. オブジェクト

3.1. オブジェクトリテラル

JavaScriptでは、オブジェクトリテラル{}を用いて、簡単にオブジェクト生成ができます。

const object = {};
 
const person = { name: "Bob", age: 25 };

他の言語のように、newで生成することも可能です。

const person = new Object();
person.name = "Bob";
person.age = 25;

また、JavaScriptはJSONをそのままオブジェクトリテラルとして解釈できます。

3.2. メソッドの型注釈

メソッド構文の引数と戻り値に型注釈を加えたような書き方になります。

let calculator: {
  sum(x: number, y: number): number;
};
 
calculator = {
  sum(x, y) {
    return x + y;
  },
};

関数構文の書き方をすると以下のようになります。

let calculator: {
  sum: (x: number, y: number) => number;
};

3.3. オブジェクトの分割代入

通常、オブジェクトからプロパティを取り出す場合は、プロパティアクセサー(ドットを使った記法)で参照します。

const color = { r: 0, g: 122, b: 204, a: 1 };
const r = color.r;
const g = color.g;
const b = color.b;
const a = color.a;

それに対して、代入分割は中カッコ{}に取り出したいプロパティを指定することで、プロパティ名と同じ名前の変数が作れます。 これは複数のプロパティを取り出したい場合に便利です。 上記と以下は同じ代入結果となります。

const color = { r: 0, g: 122, b: 204, a: 1 };
const { r, g, b, a } = color;

また、代入する変数名を指定したい場合は、以下のように記載します。

const color = { r: 0, g: 122, b: 204, a: 1 };
const { r: red, g: green, b: blue, a: alpha } = color;
console.log(green);

3.4. オプショナルチェーン

オプショナルチェーン?.を使うと、オブジェクトのプロパティが存在しない場合でも、エラーを起こさずに参照することが出来ます。

通常、以下のようなコードでは、book、authorがそれぞれundefinedとnullになっているため、参照エラーが起きてしまいます。

const book = undefined;
const title = book.title;
 
const author = null;
const email = author.email;

そこでオプショナルチェーン?.を使用することで、エラーを回避する事ができます。また、nullもしくはundefinedでないかをそれぞれチェックする方法と比べて記述量を少なくすることが出来ます。

const book = undefined;
const title = book?.title;

const author = null;
const email = author?.email;

関数を呼び出す際にも、同様にオプショナルチェーンを適用できます。

const increment = undefined;
const result = increment?.(1);
console.log(result);
 
const increment = (n) => n + 1;
const result = increment?.(1);
console.log(result);

 

4. 配列

4.1. 配列の型注釈

以下2通りの方法で型注釈をつけることが出来ます。(どちらを採用しても良い)

let array: number[];
array = [1, 2, 3];

let array: Array<number>;
array = [1, 2, 3];

4.2. 読み取り専用の配列

以下2通りの方法で読み取り専用として扱うことが出来ます。(どちらを採用しても良い)

const nums: readonly number[] = [1, 2, 3];

const nums: ReadonlyArray<number> = [1, 2, 3];

4.3. 配列の分割代入

以下のような書き方で分割代入を行うことが出来ます。

const oneToFive = [1, 2, 3, 4, 5];
const [one, two, three] = oneToFive;

4.4. 配列のスプレッド構文

通常、既存の配列に要素を追加した新しい配列を作りたい場合、以下のように記載します。

const arr = [1, 2, 3];
const arr2 = [];
for (const item of arr) {
  arr2.push(item);
}
arr2.push(4);

一方、スプレッド構文...を用いることで、以下のように短縮して記載することが出来ます。

const arr = [1, 2, 3];
const arr2 = [...arr, 4];

 

5. 型定義

5.1. 列挙型(enum)

TypeScriptでは列挙型(enum)が使えます。(JavaScriptには存在しないため、コンパイル時に変換される)

enum Position {
  Top,
  Right,
  Bottom,
  Left,
}

console.log(Position.Top); // 0
console.log(Position.Right); // 1
console.log(Position.Bottom); // 2

5.2. ユニオン型

ユニオン型は「いずれかの型」を表現します。以下のように2つ以上の型をパイプ記号|でつなげて書きます。

let numberOrUndefined: number | undefined;

以下のようにエラーコードの定義時などに便利です。

type ErrorCode =
  | 400
  | 401
  | 402
  | 403
  | 404
  | 405;

5.3. インターセクション型

インターセクション型では、オブジェクトの定義を合成することが出来ます。 以下のように、オブジェクト同士を&で列挙することで記載します。

type TwoDimensionalPoint = {
  x: number;
  y: number;
};
 
type Z = {
  z: number;
};
 
type ThreeDimensionalPoint = TwoDimensionalPoint & Z;
 
const p: ThreeDimensionalPoint = {
  x: 0,
  y: 1,
  z: 2,
};

5.4. 型エイリアス

TypeScriptでは型に名前を付けることが出来、それを型エイリアスと呼びます。 型エイリアスを宣言するときは以下のようにtypeキーワードを使います。

// プリミティブ型
type Str = string;
// リテラル型
type OK = 200;
// 配列型
type Numbers = number[];
// オブジェクト型
type UserObject = { id: number; name: string };
// ユニオン型
type NumberOrNull = number | null;
// 関数型
type CallbackFunction = (value: string) => boolean;

5.5. typeof演算子

JavaScriptのtypeof演算子を使うと、値の型を調べることが出来ます。

typeof true; //=> "boolean"
typeof 0; //=> "number"
typeof "Hello World"; //=> "string"
typeof undefined; //=> "undefined"
typeof null; //=> "object"
typeof Symbol(); //=> "symbol"
typeof 1n; //=> "bigint"
typeof [1, 2, 3]; //=> "object"
typeof { a: 1, b: 2 }; //=> "object"
typeof (() => {}); //=> "function"

 

6. おわりに

今回の記事では、第四章 読んで学ぶTypeScriptを題材に、TypeScriptの変数、オブジェクト、配列、型定義について学びました。

次回も同様に、第四章 読んで学ぶTypeScriptを題材に、TypeScriptの文、関数を中心に学んでいくつもりです。

 

7. 参考