Webエンジニア向けプログラミング解説動画をYouTubeで配信中!
▶ チャンネル登録はこちら

【ITニュース解説】Paracetamol.ts💊| #47: Explica este código TypeScript

2025年09月18日に「Dev.to」が公開したITニュース「Paracetamol.ts💊| #47: Explica este código TypeScript」について初心者にもわかりやすく解説しています。

作成日: 更新日:

ITニュース概要

TypeScriptのMapped Typesは、ある型のすべてのプロパティを別の型に必須としてマッピングする機能だ。この例では`Animal`型の要素が`ConteoAnimal`型に必須とされ、オブジェクト作成時に`conejo`プロパティが不足すると型エラーとなる。

ITニュース解説

TypeScriptは、JavaScriptというプログラミング言語に「型」という概念を導入した技術である。JavaScriptは非常に柔軟な言語だが、その自由さゆえに、特に大規模な開発では思わぬエラーが発生しやすくなることがある。TypeScriptは、変数や関数の引数、戻り値などに型情報を付与することで、プログラムの構造を明確にし、開発の初期段階で型に関するエラーを発見できるよう支援する。これにより、コードの信頼性が向上し、保守しやすく、予期せぬバグの少ない堅牢なシステムを構築することが可能になる。システムエンジニアとして、このような型システムの理解は、効率的かつ安全なソフトウェア開発において非常に重要である。

今回の記事では、TypeScriptの少し応用的な機能である「Mapped Types(マップ型)」を扱ったコードが提示されている。これを初心者にも分かりやすく順を追って解説していく。

まず、コードの最初の行 type Animal = "perro" | "gato" | "conejo"; から見ていく。 typeキーワードは、TypeScriptで新しい型を定義するために使用される。ここではAnimalという名前の新しい型を定義している。この型は、複数の特定の文字列リテラル("perro""gato""conejo")を|(パイプ)でつないだ「ユニオン型」である。ユニオン型は、「これらのうちのどれか一つ」という意味を持つ。したがって、Animal型の変数には、"perro"(犬)、"gato"(猫)、"conejo"(うさぎ)という三つの文字列のいずれかしか代入できない。例えば、"hamster"のような文字列を代入しようとすると、TypeScriptはエラーとして指摘する。これにより、入力される値の種類を厳密に制限し、プログラムの誤動作を防ぐことができる。

次に、type ConteoAnimal = { [U in Animal]: number; } というコードを見てみよう。 ここが今回の記事の核心であり、TypeScriptの「Mapped Types(マップ型)」と呼ばれる機能が使われている部分である。Mapped Typesは、既存の型(この場合はAnimal型)のプロパティ名を元にして、新しいオブジェクト型を動的に生成する強力な仕組みである。 [U in Animal]の部分は、Animal型が持つ各要素を一つずつUという一時的な変数に取り出して処理することを意味する。Animal型には"perro", "gato", "conejo"という三つの要素があるので、Uはこれらの文字列を順番に受け取る。 そして、そのUを新しいオブジェクト型の「プロパティ名」として使用し、そのプロパティの値の型を: numberと指定している。 この結果、ConteoAnimal型は次のように構築される。

  • U"perro"のとき、perroというプロパティが作られ、その値の型はnumberとなる。
  • U"gato"のとき、gatoというプロパティが作られ、その値の型はnumberとなる。
  • U"conejo"のとき、conejoというプロパティが作られ、その値の型はnumberとなる。 つまり、ConteoAnimal型は最終的に { perro: number; gato: number; conejo: number; } というオブジェクトの型として定義される。この型は、perrogatoconejoという三つのプロパティを必ず持ち、それぞれのプロパティの値が数値型であるオブジェクトであることを意味する。Mapped Typesの利点は、Animal型に新しい動物が追加された場合でも、ConteoAnimal型を手動で修正することなく、自動的に新しいプロパティが追加される点にある。これにより、コードの重複を避け、型定義の一貫性を簡単に保つことができる。

最後に、const miAnimal:ConteoAnimal = { perro:20, gato:30, } というコードを見てみよう。 ここでは、miAnimalという名前の定数を宣言し、その型を先ほど定義したConteoAnimal型として指定している。そして、{ perro:20, gato:30, } というオブジェクトをmiAnimalに代入しようとしている。 ここでTypeScriptの型チェック機能が働く。miAnimalConteoAnimal型であると宣言されているため、TypeScriptは代入しようとしているオブジェクトがConteoAnimal型のすべての要件を満たしているかを確認する。 ConteoAnimal型は、前述の通り{ perro: number; gato: number; conejo: number; } という形である。この型は、perrogatoconejoの三つのプロパティがオブジェクトに存在することを必須としている。 しかし、miAnimalに代入しようとしているオブジェクト{ perro:20, gato:30, } には、conejoプロパティが含まれていない。

このため、TypeScriptのコンパイラはエラーを発生させる。そのエラーメッセージが、記事に提示された選択肢Bの内容に完全に合致する。 B. Property 'conejo' is missing in type '{ perro: number; gato: number; }' but required in type 'ConteoAnimal' このメッセージは、「代入しようとしているオブジェクトの型({ perro: number; gato: number; })には'conejo'というプロパティが不足しているが、miAnimalの型として指定されたConteoAnimal型ではそのプロパティが必須である」という意味である。ConteoAnimal型でconejoプロパティが必須とされているのは、Mapped TypesによってAnimal型のすべての要素がキーとして取り込まれるためである。

このように、TypeScriptのMapped Typesは、既存の型に基づいて新しい型を柔軟に、かつ自動的に生成できる強力な機能である。これにより、開発者は型定義の繰り返し作業を減らし、コードの整合性を維持しやすくなる。今回の例のように、ある列挙可能な値のリストに対して、それぞれに対応するプロパティを持つオブジェクトの型を強制したい場合に非常に有効であり、システム全体の構造をより厳密に定義し、潜在的な型関連のバグを未然に防ぐことに貢献する。システムエンジニアを目指す上で、このような型システムの理解は、より信頼性の高いソフトウェア開発を進めるための重要な一歩となるだろう。

関連コンテンツ