TypeScript PR

【TypeScript】Pick型でピックアップ!?必要なプロパティだけを抽出しよう

【TypeScript】Pick型でピックアップ!?必要なプロパティだけを抽出しよう
記事内に商品プロモーションを含む場合があります

こんにちは!

TypeScriptで特定の型から必要なプロパティだけを抽出したいと思ったことはありませんか?

オブジェクトの一部のプロパティだけを持つ新しい型を定義したいけど、どうすればいいんだろう?
複数のインターフェースから必要なものだけを組み合わせて使いたい!
コードの可読性を高めたいけど、もっと良い方法はないかな?

このような悩みを抱えている方もいるのではないでしょうか。

この記事では、TypeScriptのPick型について、基本的な使い方から具体的な活用例、注意点までを徹底的に解説します。

この記事は次のような人におすすめです。

この記事はこんな人におすすめ!
  • TypeScriptのPick型について詳しく知りたい
  • オブジェクトの一部のプロパティだけを持つ型を効率的に定義したい
  • Pick型の具体的な使い方や活用例を学びたい
  • Pick型を使う上での注意点を知っておきたい

この記事を読めば、TypeScriptのPick型を完全に理解し、実務での開発に自信を持って活用できるようになります。
さらに、コードの可読性や保守性を向上させるためのコツもお伝えしています。

「TypeScriptの型定義で悩んでいる方」「効率的に型を定義したい方」は、ぜひ参考にしてください。

それでは、順を追って詳しく見ていきましょう!

そもそもTypeScriptのPick型とは?

まずは、TypeScriptのPick型について、基本的な概念をしっかり理解しましょう。

Pick型は、既存の型から指定したプロパティだけを抽出して新しい型を生成するユーティリティ型です。
簡単に言えば、「ある型の一部分を切り取って、新しい型を作る」イメージです。

Pick<T, K>という形式で記述し、Tには元の型、Kには抽出したいプロパティ名を指定します。Kは文字列のリテラル型または文字列リテラル型のユニオン型で指定します。

例えば、以下のようなUser型があるとします。

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

このUser型から、idnameプロパティだけを持つ新しい型を作りたい場合、Pick型を使うと簡単に実現できます。

type UserName = Pick<User, 'id' | 'name'>;
// UserName型は { id: number, name: string } となる

このように、Pick型を使うと、必要なプロパティだけを抽出して新しい型を柔軟に定義できます。
特に、オブジェクト型が複雑になるほど、その恩恵は大きくなります。

TypeScript Pick型のメリット

TypeScriptのPick型を利用することには、いくつかの具体的なメリットがあります。主なメリットを詳しく見ていきましょう。

型定義の効率化

Pick型を使うと、既存の型から必要なプロパティだけを簡単に抽出できるため、同じような型を何度も定義する手間を省けます。これは、特に大規模なプロジェクトや複雑な型を扱う際に非常に有効です。型定義が簡潔になることで、コード全体の可読性も向上します。

型の再利用性向上

Pick型で抽出した型は、他の型定義で再利用できます。これにより、コードの重複を減らし、保守性を高めることができます。例えば、User型からUserName型を作成した後、別の場所でUserName型を再利用して、UserName型のプロパティだけを持つ別の型を作ることが可能です。

型の柔軟性向上

Pick型は、元の型の一部分だけを使用するため、さまざまな場面に応じて柔軟に型を定義できます。

例えば、APIのレスポンスから特定のデータだけを取得して使う場合に便利です。Pick型を使うことで、APIレスポンスの型全体を定義することなく、必要な部分だけを定義できます。

コードの可読性向上

型定義が複雑になると、コード全体の可読性が低下する可能性があります。しかし、Pick型を使うことで、型定義の意図を明確に表現できます。どのプロパティが抽出されているかが一目でわかるため、コードの理解が容易になります。

不要なプロパティの排除

Pick型を使うことで、必要なプロパティだけを抽出できます。これにより、不要なプロパティによるバグのリスクを減らすことができます。型定義の段階で、必要なプロパティのみを制限することで、開発中の予期せぬエラーを防ぐことに繋がります。

これらのメリットを考えると、TypeScriptのPick型は、開発効率とコード品質の両方を高める上で非常に有効なツールと言えるでしょう。

TypeScript Pick型の具体的な使い方

それでは、Pick型の具体的な使い方を、具体的なコード例を交えながら解説します。

基本的な使い方

まずは、Pick型の基本的な使い方をみていきましょう。
先ほどのUser型を使って説明します。

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

このUser型から、idnameプロパティだけを抽出して、UserName型を定義する場合は、以下のようになります。

type UserName = Pick<User, 'id' | 'name'>;

const user: UserName = {
  id: 1,
  name: 'taro'
};
// エラーにならない

const invalidUser: UserName = {
  id: 1,
  email: 'test@example.com'
  // エラーになる:プロパティ 'email' は型 'Pick<User, "id" | "name">' に存在しません。
};

const invalidUser2: UserName = {
  name: 'taro',
  age: 20
  // エラーになる:型 '{ name: string; age: number; }' を型 'Pick<User, "id" | "name">' に割り当てることはできません。プロパティ 'id' が型 'Pick<User, "id" | "name">' にありません。
};

このように、Pick型を使うことで、User型の一部のプロパティだけを持つ型を簡単に定義できます。
UserName型はidプロパティとnameプロパティだけを持つため、それ以外のプロパティを持つオブジェクトを代入しようとすると、TypeScriptのエラーが発生します。

複数のプロパティを抽出する

Pick型では、複数のプロパティを抽出することも可能です。
先ほどのUser型から、id, name, email プロパティを持つUserContact型を定義する場合、以下のようにします。

type UserContact = Pick<User, 'id' | 'name' | 'email'>;

const userContact: UserContact = {
  id: 1,
  name: 'taro',
  email: 'test@example.com'
};
// エラーにならない

複数のプロパティを指定する場合は、| (OR演算子)で区切って指定します。

オプショナルなプロパティを指定する

Pick型では、元の型にオプショナルなプロパティが含まれている場合、そのオプショナルな性質も維持されます。
例えば、User型にageプロパティがオプショナル(age?: number)として定義されていたとします。

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

このUser型から、idageプロパティを抽出すると、ageプロパティもオプショナルになります。

type UserAge = Pick<User, 'id' | 'age'>;
const userAge1: UserAge = { id: 1 };
// エラーにならない: ageはオプショナルなので指定しなくてもエラーにならない
const userAge2: UserAge = { id: 1, age: 20 };
// エラーにならない

Pick型は元の型のプロパティのオプショナルな性質を維持するため、柔軟に型を定義することができます。

他の型と組み合わせる

Pick型は、他の型と組み合わせて使うこともできます。例えば、Pick型で抽出した型を、別の型で使うことも可能です。
以下のように、UserContact型とUserAge型を組み合わせてUserInfo型を定義できます。

type UserContact = Pick<User, 'id' | 'name' | 'email'>;
type UserAge = Pick<User, 'id' | 'age'>;

type UserInfo = UserContact & UserAge;
const userInfo: UserInfo = {
  id: 1,
  name: 'test',
  email: 'test@example.com',
  age: 20
};
// エラーにならない

このように、Pick型は他の型と組み合わせて使うことで、さらに柔軟に型定義できます。

Pick型を使う上での注意点

Pick型は便利な反面、使用する上での注意点もいくつか存在します。具体的な注意点を詳しく解説します。

存在しないプロパティを指定した場合

Pick型で、元の型に存在しないプロパティを指定した場合、TypeScriptはコンパイルエラーを起こします。
例えば、User型に存在しないaddressプロパティを指定した場合、以下のようになります。

type InvalidUser = Pick<User, 'id' | 'address'>;
// エラーになる:型 'User' に型 ''address'' のプロパティがありません。

Pick型を使う際は、元の型に存在するプロパティを正しく指定する必要があります。タイプミスなどがないように注意しましょう。
コンパイルエラーが発生するため、事前に間違いに気づけますが、注意して記述する必要があります。

型の変更による影響

元の型定義が変更された場合、その型から派生したPick型も影響を受ける可能性があります。
例えば、User型からUserName型を作成後、User型に新しいプロパティが追加された場合、UserName型にはその影響はありません。

しかし、User型からプロパティが削除された場合は、UserName型の定義にエラーが発生する可能性があります。
特に、複数の場所でPick型を使用している場合、変更による影響範囲を十分に考慮する必要があります。
型定義の変更を行う際は、影響範囲を十分に確認してから行うようにしましょう。

ネストされたオブジェクトの扱い

Pick型では、ネストされたオブジェクトのプロパティを個別に選択することはできません。ネストされたオブジェクトは常に全体が選択されます。

interface User {
  id: number;
  name: string;
  profile: {
    age: number;
    email: string;
    address: string;
  };
}

type UserNameAndAge = Pick<User, 'name' | 'age'>;
// エラーになる:型 '"name" | "age"' は制約 'keyof User' を満たしていません。型 '"age"' を型 'keyof User' に割り当てることはできません。
type UserNameAndProfile = Pick<User, 'name' | 'profile'>;
// profileを指定すると全プロパティが含まれる

この制約を理解せずに使用すると、意図しない型の依存関係が生まれる可能性があるので注意しましょう。基本的には、ネストが必要な場合は事前にインターフェースを分割して定義することを推奨します。

interface User {
  id: number;
  name: string;
  profile: Profile;
}

interface Profile {
  age: number;
  email: string;
  address: string;
}

type UserNameAndAge = Pick<User, 'name'> & Pick<Profile, 'age'>;

具体的な利用シーン

Pick型は、さまざまな場面で活用できます。ここでは、具体的な利用シーンをいくつかご紹介します。

APIレスポンスの型定義

APIからのレスポンスデータを扱う際、全てのプロパティが必要とは限りません。
Pick型を使うことで、必要なデータだけを持つ型を効率的に定義できます。
例えば、User型がAPIレスポンスとして返ってくる場合、特定の画面ではidnameだけが必要だとします。

interface UserResponse {
  id: number;
  name: string;
  email: string;
  age: number;
  address: string;
  createdAt: string;
  updatedAt: string;
}
// APIレスポンスの型から、必要な部分だけを抽出
type UserName = Pick<UserResponse, 'id' | 'name'>;

async function fetchUser(): Promise<UserName> {
  //APIからユーザー情報を取得する
  const response: UserResponse = await fetch('...').then(res => res.json());
  //APIレスポンスから必要なデータだけを抽出して返す
  return {
    id: response.id,
    name: response.name
  };
}

このように、Pick型を利用して、必要な部分だけを定義することで、不要なプロパティによるバグを避けることができます。

フォームの入力値の型定義

フォームの入力値を扱う際、全て入力必須ではないケースもあります。
Pick型を利用して、フォームの入力に必要なプロパティだけを抽出して型を定義することができます。
User型でフォーム入力が必要なのがnameemailのみの場合、以下のようにUserForm型を定義できます。

interface User {
  id: number;
  name: string;
  email: string;
  age: number;
}
type UserForm = Pick<User, 'name' | 'email'>;

function submitForm(formValue: UserForm) {
  // フォームの値を送信する処理
  console.log(formValue);
}
submitForm({
  name: 'test',
  email: 'test@example.com'
});
// エラーにならない

submitForm({
  id: 1, // エラーになる:オブジェクト リテラルは既知のプロパティのみ指定できます。'id' は型 'UserForm' に存在しません。
  name: 'test',
  email: 'test@example.com'
});

Pick型を使うことで、必要な入力値だけを持つ型を定義し、安全にフォームを扱うことができます。

型の共通部分を抽出する

複数のインターフェース間で共通のプロパティを持つ場合、Pick型を使って共通部分を抽出できます。
例えば、Product型とOrder型に共通のidnameプロパティがあるとします。

interface Product {
  id: number;
  name: string;
  price: number;
}

interface Order {
  id: number;
  name: string;
  quantity: number;
}

type ItemInfo = Pick<Product, 'id' | 'name'>;

function processItem(item: ItemInfo) {
  // 共通の処理を記述
  console.log(item);
}

const product: Product = {
  id: 1,
  name: 'test',
  price: 100
};

const order: Order = {
  id: 1,
  name: 'test',
  quantity: 1
};
// それぞれの型を引数に渡すことができる
processItem(product);
processItem(order);

Pick型を使用することで、異なる型間で共通のプロパティだけを抽出して、共通の処理を定義することが可能になります。

特定の型から特定のプロパティを除外する

Pick型を応用して、ある型から特定のプロパティを除外した型を作ることも可能です。
Exclude型と組み合わせることで実現できます。

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

type UserWithoutId = Pick<User, Exclude<keyof User, 'id'>>;
// UserWithoutId は { name: string, email: string, age: number } となる

const user: UserWithoutId = {
  name: 'test',
  email: 'test@example.com',
  age: 20
};

const invalidUser: UserWithoutId = {
  id: 1, // オブジェクト リテラルは既知のプロパティのみ指定できます。'id' は型 'UserWithoutId' に存在しません。
  name: 'test',
  email: 'test@example.com',
  age: 20
};

このように、Exclude型とPick型を組み合わせることで、特定のプロパティを除外した型を定義することができます。

これらの例からわかるように、Pick型はさまざまな場面で非常に柔軟に活用できることがわかります。
ぜひ、Pick型をマスターして、より効率的なTypeScript開発を目指しましょう。

【付録】さらに学びを深めるためのリソース


intersection型について理解を深めたところで、さらに学習を進めたい方のために、いくつかのリソースを紹介します。
これらのリソースを活用することで、TypeScriptの型システムについてより深い知識を得ることができるでしょう。

おすすめの書籍


プロを目指す人のためのTypeScript入門


プロ開発者への近道!基礎から応用まで幅広くカバー

1一番のおすすめは「プロを目指す人のためのTypeScript入門」です。
この本は、TypeScriptの基礎から高度な使い方まで幅広く解説しています。

初心者でも理解しやすい説明から始まり、徐々に難易度を上げていく構成が特徴。
プログラミング経験者なら、さらに深い理解が得られるでしょう。

実際の開発現場で使えるテクニックも豊富に紹介されているのがポイント。
型の使い方や設計パターンなど、実践的な内容が満載です。

プロの開発者を目指す人はもちろん、TypeScriptをしっかり学びたい人におすすめの一冊。
基礎固めから応用力の向上まで、幅広いニーズに応えてくれます。

現場で使えるTypeScript 詳解実践ガイド


実践的スキルを身につけたい人必見!現場のノウハウが詰まった一冊

次におすすめは「現場で使えるTypeScript 詳解実践ガイド」がランクイン。
この本の特徴は、実際の開発現場で役立つ知識が詰まっていること。

TypeScriptの基本的な文法から始まり、実際のプロジェクトでどう活用するかまで丁寧に解説しています。
エラー対処法や性能改善のコツなど、現場ならではの知恵も満載。

特に、大規模なプロジェクトでTypeScriptを使う際のベストプラクティスが学べるのが魅力。
コードの保守性や再利用性を高める方法も詳しく紹介されています。

すでにJavaScriptの経験がある人や、実務でTypeScriptを使いたい人におすすめ。
この本を読めば、現場で即戦力として活躍できる力が身につくはずです。

書籍に関してはこちらの記事も参考にしてくださいね!




オンラインで参照できる公式ドキュメント


TypeScript公式ハンドブック


https://www.typescriptlang.org/docs/
TypeScriptの公式ドキュメントです。
intersection型を含む、すべての型システムの機能について詳細な説明があります。

TypeScript Deep Dive


https://basarat.gitbook.io/typescript/
TypeScriptの深い部分まで掘り下げて解説しているオンラインブックです。
無料で読むことができ、intersection型についても詳しく説明されています。

TypeScriptの学習は終わりがありません。
新しい機能が常に追加され、より良い書き方が発見されています。
継続的に学習を続けることで、より良いTypeScriptプログラマーになれるはずです。

キャリア形成/給与還元
ひとつひとつ真摯に向き合う企業
ONE_WEDGE社員募集

株式会社 ONE WEDGEでは、新たな仲間を募集しています!

私たちと一緒に、革新的で充実したキャリアを築きませんか?
当社は、従業員が仕事と私生活のバランスを大切にできるよう、充実した福利厚生を整えています。

  • 完全週休2日制(土日休み)で、祝日や夏季休暇、年末年始休暇もしっかり保証!
  • 様々な休暇制度(有給、慶弔、産前・産後、育児、バースデー休暇)を完備!
  • 従業員の成長と健康を支援するための表彰制度、資格取得支援、健康促進手当など!
  • 生活を支えるテレワーク手当、記事寄稿手当、結婚祝金・出産祝金など、様々な手当を提供!
  • 自己啓発としての書籍購入制度や、メンバー間のコミュニケーションを深める交流費補助!
  • 成果に応じた決算賞与や、リファラル採用手当、AI手当など、頑張りをしっかり評価!
  • ワークライフバランスを重視し、副業もOK!

株式会社 ONE WEDGEでは、一人ひとりの従業員が自己実現できる環境を大切にしています。
共に成長し、刺激を与え合える仲間をお待ちしております。
あなたの能力と熱意を、ぜひ当社で発揮してください。
ご応募お待ちしております!

ホームページ、採用情報は下記ボタンからご確認ください!

応募、ご質問など、LINEでお気軽にご相談ください♪

まとめ

ここまで、TypeScriptのPick型について、詳しく解説してきました。改めて、重要なポイントをおさらいしましょう。

  • Pick型は、既存の型から指定したプロパティだけを抽出できる
  • 型定義の効率化、再利用性、柔軟性、可読性の向上に役立つ
  • 元の型に存在しないプロパティを指定するとエラーになる
  • 型変更による影響を考慮する必要がある
  • ネストされたオブジェクトの型定義に注意が必要
  • APIレスポンス、フォームの入力値、共通部分の抽出など、様々な場面で活用できる
  • Exclude型と組み合わせることで、特定のプロパティを除外できる

Pick型は、TypeScriptの型定義をより柔軟にし、効率的な開発を実現するための強力なツールです。
使いこなすことで、型定義の手間を削減し、コードの品質を向上させることができます。

また、Pick型は、他のTypeScriptの機能と組み合わせることで、さらに強力な型定義を行うことができます。例えば、Partial型やOmit型などと組み合わせることで、より柔軟な型定義が可能になります。

今回ご紹介した内容を参考に、ぜひPick型を活用してみてください。

COMMENT

メールアドレスが公開されることはありません。 が付いている欄は必須項目です