みなさん、こんにちは!システムエンジニアでブロガーの私が、今日はTypeScriptの型システムについて詳しくご紹介します。TypeScriptを使うと、JavaScriptでは実現しにくかった「型の安全性」を確保できるので、エラーを減らし、より読みやすいコードを書くことができますよね。でも、型推論や型アノテーションなど、色々な用語が出てきて混乱しちゃうこともあるのではないでしょうか?今日はそんなあなたのために、TypeScriptの型システムをやさしく解説していきます。高校生でもわかるように丁寧に説明していくので、一緒に勉強していきましょう!
型推論(Type Inference)
TypeScriptのすごいところは、コードを書くだけで自動的に型を推測してくれる「型推論」があることです。型を明示的に書かなくても、TypeScriptが賢く判断してくれるので便利です。
let message = "Hello, TypeScript!";
このコードでは、message
変数は文字列として扱われます。let
を使って変数を宣言しましたが、string
という型を自動で推論してくれるので、message
には文字列しか代入できません。
例えば、次のように数値を代入しようとするとエラーが出ます。
message = 42; // エラー: 型 'number' を型 'string' に割り当てることはできません
TypeScriptが「待って!それは文字列じゃないよ!」と教えてくれるので安心ですね。
型アノテーション(Type Annotation)
でも、どうしても型を明示したい場合は「型アノテーション」を使います。これにより、変数や関数の引数の型を明確に指定することができます。
let age: number = 25;
この場合、age
はnumber
型として宣言されているので、数値しか代入できません。
age = "twenty-five"; // エラー: 型 'string' を型 'number' に割り当てることはできません
明示的に型を書いてあげることで、コードの読みやすさがぐっと上がりますね。
型アサーション(Type Assertion)
ときには、「TypeScriptよ、これは私がちゃんとわかっているから心配しないで!」と伝えたくなる場面があります。そんなときには「型アサーション」を使います。型アサーションを使うと、TypeScriptに「この変数はこの型だと見なしてくれ」と伝えることができます。
let someValue: any = "This is a string"; let strLength: number = (someValue as string).length;
someValue
はany
型ですが、「これは文字列だから」としてas string
を使って型を変換し、length
を取得しています。
オプショナル(Optional)
TypeScriptでは、オプショナルなプロパティを定義することもできます。これは「このプロパティはあってもなくてもいいよ」という意味です。
interface User { name: string; age?: number; // `age` はオプショナル } let user: User = { name: "John" }; // `age` がなくてもOK
この場合、age
プロパティはあってもなくてもよいので、user
オブジェクトを定義する際に省略できます。
列挙型(Enum)
列挙型は、特定の値のセットを表すために使います。例えば、曜日を表すときに役立ちます。
enum Direction { Up, Down, Left, Right } let move: Direction = Direction.Up;
Direction
という名前の列挙型を定義し、Up
, Down
, Left
, Right
といった定数を持たせました。このようにして、コードの中で誤った値が入りにくくなります。
Tuple型
TypeScriptのtuple
は、異なる型を固定長で持つ配列のようなものです。例えば、string
とnumber
のペアを扱いたいときに便利です。
let userInfo: [string, number] = ["Alice", 30];
userInfo
は、最初の要素がstring
、次の要素がnumber
という形式を強制されます。逆にするとエラーになります。
userInfo = [30, "Alice"]; // エラー: 型 'number' は型 'string' に割り当てられません
any型とunknown型
any
型は、何でも受け入れる万能型です。型チェックを完全に無視してくれるので、初心者がついつい頼りたくなりますが、なるべく避けるようにしましょう。any
を多用すると、TypeScriptを使う意味が薄れてしまいます。
let something: any = "hello"; something = 42; something = true;
unknown
型は、any
に似ていますが、使用する際には注意が必要です。unknown
型の変数を使うには、その型が何であるかを確認する必要があります。
let value: unknown = "Hello"; if (typeof value === "string") { console.log(value.toUpperCase()); // 型が 'string' であることを確認したので安全に使える }
unknown
を使うことで、少しだけ型安全性を確保しながら柔軟性も得られます。
サンプルコードの実行結果
ここまで説明した内容をまとめたサンプルコードを実行してみましょう。
enum Role { Admin, User, Guest } interface UserProfile { username: string; role: Role; age?: number; } let admin: UserProfile = { username: "Alice", role: Role.Admin }; let user: UserProfile = { username: "Bob", role: Role.User, age: 25 }; console.log(admin.username); // 出力: Alice console.log(user.age); // 出力: 25
UserProfile
インターフェースを使い、role
には列挙型Role
を使用しています。age
はオプショナルなので、admin
には指定せず、user
には指定しています。
次回のテーマとお知らせ
いかがでしたでしょうか?TypeScriptの型システムについて少しでも理解が深まったなら嬉しいです!次回は、TypeScriptで使うことができるクラスとインターフェースの違いについて、さらに詳しくお話ししていきます。クラスやインターフェースを上手に使って、よりオブジェクト指向的なプログラミングを学んでいきましょう!
もしこの記事が役に立ったら、ぜひツイッターでフォローして、最新情報をゲットしてくださいね。それでは、また次回お会いしましょう!