TypeScriptで型定義を行う基本|プリミティブ型とオブジェクト型

先生

TypeScriptの型定義、難しそう?いえいえ、基本からしっかり学べば怖くない!プリミティブ型とオブジェクト型をマスターして、安全なコードを書こう!

TypeScriptの型定義:基本をマスターしよう

TypeScriptは、JavaScriptに静的型付けを加えた言語です。型定義をすることで、コードの品質が向上し、開発効率も上がります。この記事では、TypeScriptの基本的な型定義について、プリミティブ型とオブジェクト型を中心に解説します。

型定義は、変数や関数の引数、戻り値などがどのようなデータ型を持つかを明示的に指定することです。これにより、コンパイル時に型エラーを検出でき、実行時のエラーを減らすことができます。

TypeScriptの型定義は、JavaScriptのコードに型情報を付加する形で記述します。そのため、JavaScriptの知識があれば比較的容易に学習できます。

プリミティブ型:基本中の基本

TypeScriptには、いくつかの基本的なプリミティブ型があります。これらはJavaScriptにも存在する基本的なデータ型です。

number型: 数値を表します。整数、浮動小数点数など、すべての数値をnumber型として扱います。

let age: number = 30;
let price: number = 9.99;

string型: 文字列を表します。シングルクォート(”)またはダブルクォート(“”)で囲みます。

let name: string = "Taro";
let message: string = 'Hello, world!';

boolean型: 真偽値を表します。trueまたはfalseのいずれかの値を持ちます。

let isAdult: boolean = true;
let isEnabled: boolean = false;

null型とundefined型: nullundefinedは、それぞれ値が存在しないことを表します。 TypeScript 2.0以降では、--strictNullChecksオプションを使用すると、nullundefinedを明示的に型として扱う必要が出てきます。

let nullableValue: string | null = null; // string型またはnull型
let undefinedValue: number | undefined = undefined; // number型またはundefined型

symbol型: ES2015で導入された型で、一意な識別子を作成するために使用されます。

const sym1: symbol = Symbol("key1");
const sym2: symbol = Symbol("key1");

console.log(sym1 === sym2); // false

bigint型: ES2020で導入された型で、Number型で扱える最大値を超える整数を扱う際に使用します。

const bigIntLiteral: bigint = 100n;
const bigIntConstructor: bigint = BigInt(100);

これらのプリミティブ型を理解することは、TypeScriptで型定義を行う上で非常に重要です。

オブジェクト型:複雑なデータを扱う

オブジェクト型は、プリミティブ型を組み合わせて、より複雑なデータを表現するために使用します。TypeScriptでは、オブジェクトの構造を型として定義できます。

インターフェース (interface): オブジェクトの構造を定義するための強力な機能です。インターフェースを使用することで、オブジェクトが持つべきプロパティとその型を明確にすることができます。

interface User {
  id: number;
  name: string;
  email: string;
}

上記の例では、Userインターフェースは、id(number型)、name(string型)、email(string型)の3つのプロパティを持つオブジェクトを表します。

let user: User = {
  id: 123,
  name: "Hanako",
  email: "hanako@example.com"
};

インターフェースは、クラスの構造を定義するためにも使用できます。

型エイリアス (type alias): 既存の型に別の名前を付けることができます。オブジェクトの型を定義するためにも使用できます。

type Point = {
  x: number;
  y: number;
};
let point: Point = {
  x: 10,
  y: 20
};

型エイリアスは、インターフェースと似たような機能を提供しますが、いくつかの違いがあります。例えば、型エイリアスは共用体型 (union type) や交差型 (intersection type) を定義するのに適しています。

配列 (array): 同じ型の要素を複数格納できるデータ構造です。

let numbers: number[] = [1, 2, 3, 4, 5];
let names: string[] = ["Alice", "Bob", "Charlie"];

配列の型は、要素の型の後に[]を付けることで定義します。 ジェネリクスを利用して Array<number> のように記述することも可能です。

タプル (tuple): 型の異なる要素を複数格納できるデータ構造です。配列とは異なり、タプルは要素の型と数が固定されています。

let person: [string, number] = ["Taro", 30];

上記の例では、personは文字列と数値を格納できるタプルです。タプルは、複数の値をまとめて返したい場合などに便利です。

関数における型定義

関数においても、引数と戻り値の型を定義することが重要です。これにより、関数の使い方が明確になり、型エラーを事前に検出できます。

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

上記の例では、add関数は2つのnumber型の引数を取り、number型の値を返します。

let result: number = add(5, 3); // resultは8

アロー関数を使用する場合も同様に型定義を行います。

const multiply = (x: number, y: number): number => {
  return x * y;
};

また、引数が省略可能であることを示すためには?を使用します。

function greet(name?: string): string {
  if (name) {
    return Hello, ${name}!;
  } else {
    return "Hello!";
  }
}

この例では、name引数は省略可能です。省略された場合は、undefinedとして扱われます。

参考リンク

まとめ

この記事では、TypeScriptの基本的な型定義について解説しました。プリミティブ型とオブジェクト型を理解し、適切に型定義を行うことで、より安全で保守性の高いコードを書くことができます。積極的に型定義を活用し、TypeScriptの恩恵を最大限に享受しましょう。