【TypeScript入門】第2回:基本の型を学ぶ~プリミティブ型から関数まで

目次

前回の第1回では、TypeScriptの基本的な特徴と開発環境のセットアップについて学びました。TypeScriptの最大の特徴の一つは、JavaScriptに「静的型付け」という強力な機能を追加することです。この型システムがあることで、コードの記述中にエラーを発見しやすくなったり、予測しやすい、より堅牢なプログラムを作成できるようになります。

今回の第2回では、TypeScriptの型システムを理解するための最初のステップとして、最も基本的な「型」について詳しく学んでいきます。具体的には、数値や文字列といったプリミティブ型、複数のデータを扱う配列、複雑な構造を持つオブジェクト、そしてプログラムの振る舞いを定義する関数の型付け方法を習得します。

これらの基本をしっかりと押さえることで、TypeScriptを使った開発の基礎が築かれ、より安全で効率的なコーディングが可能になります。実際にコードを書きながら、それぞれの型の使い方をマスターしていきましょう。

デザイナー

静的型付けって聞くと難しそうだけど、実は開発体験を大きく向上させてくれるんだね!

2.1 プリミティブ型

プリミティブ型は、TypeScript(そしてJavaScript)における最も基本的なデータ型です。数値、文字列、真偽値などがこれにあたります。TypeScriptでは、これらのデータに明示的に型を注釈することで、意図しない型の代入を防ぎ、より安全なコードを書くことができます。

基本的なプリミティブ型は以下の通りです。

  • number: 数値(整数、浮動小数点数)
  • string: 文字列
  • boolean: 真偽値(true または false
  • null: 値がないことを示す特殊な値
  • undefined: 値が未定義であることを示す特殊な値

変数に型を注釈するには、変数名の後にコロン : と型名を記述します。

// number型
let age: number = 30;
// age = ""twenty""; // エラー: string型をnumber型に代入することはできません。

// string型
let userName: string = ""Alice"";
// userName = 123; // エラー: number型をstring型に代入することはできません。

// boolean型
let isActive: boolean = true;
// isActive = 0; // エラー: number型をboolean型に代入することはできません。

// nullとundefined
let data: null = null;
let value: undefined = undefined;

TypeScriptには「型推論」という便利な機能もあります。これは、変数を宣言したときに初期値を指定すると、TypeScriptが自動的にその変数の型を推測してくれる機能です。これにより、毎回明示的に型を記述しなくても、型チェックの恩恵を受けることができます。

let inferredNumber = 100; // inferredNumberはnumber型と推論されます
let inferredString = ""TypeScript""; // inferredStringはstring型と推論されます
let inferredBoolean = false; // inferredBooleanはboolean型と推論されます

// 型推論された変数も、一度型が決まると異なる型の値を代入できません。
// inferredNumber = ""Hello""; // エラー
エンジニア

型推論はすごく便利だけど、特に意識して型を記述するメリットもあるってことだね。

2.2 配列 (Array)

配列は、複数の値を順序付けて格納するためのデータ構造です。TypeScriptで配列を扱う場合、配列がどのような型の要素を持つのかを定義します。

配列の型を定義する方法は主に2つあります。

  1. 要素の型名の後に [] を付ける方法: Type[]
  2. ジェネリックな Array 型を使用する方法: Array<Type>

どちらの方法も同じ意味で使われます。

// 数値型の配列
let numbers: number[] = [1, 2, 3, 4, 5];
let temperatures: Array<number> = [25.5, 26.0, 24.8];

// numbers.push(""six""); // エラー: string型をnumber型に代入することはできません。

// 文字列型の配列
let fruits: string[] = [""apple"", ""banana"", ""orange""];

// ユニオン型(複数の型を許容する)の配列
// 配列の要素が複数の型の可能性がある場合、「|」(パイプ)を使ってユニオン型を定義します。
let mixedArray: (string | number)[] = [""hello"", 123, ""world"", 456];
デザイナー

ユニオン型を使うと、柔軟性と型安全性を両立できるのがTypeScriptの強みだね。

2.3 オブジェクト (Object)

オブジェクトは、キーと値のペアで構成されるデータ構造です。TypeScriptでは、オブジェクトがどのようなプロパティを持ち、それぞれのプロパティがどのような型であるかを定義することができます。

オブジェクトの型を定義する方法はいくつかありますが、ここではオブジェクトリテラルと型エイリアス(type)について説明します。

オブジェクトリテラルによる型定義

オブジェクト変数を宣言する際に、直接その構造を定義する方法です。

// オブジェクトの型定義
let user: {
  id: number;
  name: string;
  email?: string; // プロパティ名の後に ? を付けると、そのプロパティはオプショナル(省略可能)になります。
} = {
  id: 1,
  name: ""Bob"",
  email: ""bob@example.com"",
};

// オプショナルプロパティは省略してもエラーになりません。
let admin: {
  id: number;
  name: string;
  email?: string;
} = {
  id: 2,
  name: ""Charlie"",
};

// user.id = ""new ID""; // エラー: string型をnumber型に代入することはできません。

型エイリアス (type) の使用

同じオブジェクトの型を何度も記述するのは非効率です。type キーワードを使って、オブジェクトの型に名前を付け、再利用可能なエイリアス(別名)を作成できます。

// 型エイリアスの定義
type UserProfile = {
  id: number;
  name: string;
  email?: string;
  readonly createdAt: Date; // readonlyを付けると、プロパティは初期化後に変更できなくなります。
};

// 定義した型エイリアスを使ってオブジェクトを作成
let user1: UserProfile = {
  id: 1,
  name: ""Alice"",
  email: ""alice@example.com"",
  createdAt: new Date(),
};

let user2: UserProfile = {
  id: 2,
  name: ""Bob"",
  createdAt: new Date(""2023-01-01""),
};

console.log(user1.name); // 出力: Alice

// user1.createdAt = new Date(); // エラー: 'createdAt' は読み取り専用プロパティのため、割り当てできません。
エンジニア

typeエイリアスとreadonlyは、大規模なアプリケーション開発で特に役立ちそうだね!

2.4 関数 (Function)

関数は、特定の処理を実行するコードのブロックです。TypeScriptでは、関数の引数と戻り値(返り値)の型を明確に指定することができます。これにより、関数がどのようなデータを受け取り、どのようなデータを返すのかが明確になり、誤った使い方を防ぐことができます。

引数と戻り値の型指定

引数には変数と同様に : と型名を記述し、戻り値の型は関数の仮引数リストの閉じカッコ ) の後に : と型名を記述します。

// 関数の引数と戻り値の型指定
function add(a: number, b: number): number {
  return a + b;
}

console.log(add(5, 3)); // 出力: 8
// console.log(add(""hello"", 3)); // エラー: string型をnumber型に代入することはできません。

// アロー関数での型指定も同様です。
const multiply = (a: number, b: number): number => {
  return a * b;
};

console.log(multiply(4, 2)); // 出力: 8

戻り値がない (void) 関数

関数が何も値を返さない場合、戻り値の型として void を指定します。これは、JavaScriptの関数が明示的に return を記述しない場合に undefined を返すのと似ていますが、TypeScriptではその意図を void で表現します。

// 戻り値がない(void)関数
function greet(name: string): void {
  console.log(`Hello, ${name}!`);
}

greet(""TypeScript""); // 出力: Hello, TypeScript!

// 関数を変数に代入する場合の型定義
type GreetFunction = (name: string) => void;

const sayHello: GreetFunction = (userName: string) => {
  console.log(`Nice to meet you, ${userName}.`);
};

sayHello(""Developer"");
デザイナー

voidは直感的に理解しやすいし、関数の意図を明確にできるから良いね。

まとめ

今回はTypeScriptの基本的な型について深く掘り下げて学びました。

  • プリミティブ型: number, string, boolean, null, undefined と、TypeScriptの型推論の仕組みを理解しました。
  • 配列: Type[] または Array<Type> 構文を使って、配列の要素の型を定義する方法を習得しました。
  • オブジェクト: オブジェクトリテラルや type エイリアスを使って、複雑なデータ構造に型を付ける方法、オプショナルプロパティや読み取り専用プロパティの概念を学びました。
  • 関数: 引数と戻り値に型を付け、関数の安全性を高める方法、また void 型を使って戻り値がない関数を表現する方法を理解しました。

これらの基本の型を使いこなすことで、TypeScriptの型システムの恩恵を最大限に受けることができます。コードの記述時に型に関するエラーを検出しやすくなるだけでなく、コードの可読性や保守性も向上します。

次回は、今回学んだ基本的な型を組み合わせる方法や、より柔軟な型定義を可能にするユニオン型、インターセクション型、リテラル型といった概念について詳しく見ていきます。これらの発展的な型を学ぶことで、さらに表現力豊かなTypeScriptのコードを書けるようになるでしょう。

エンジニア

基本的な型をしっかりマスターすれば、TypeScriptのコードを読むのも書くのも楽しくなるはずだよ!

コメントを残す

入力エリアすべてが必須項目です。メールアドレスが公開されることはありません。

内容をご確認の上、送信してください。