TypeScriptの魔法!オブジェクトの形を自在に変える「組み込みユーティリティ型」の秘密
やっほー!フロントエンドの沼にどっぷり浸かってるみんな、元気?✨
突然だけど、TypeScriptって「型」でコードをカチッと守ってくれる、まるで優秀な秘書みたいな存在だよね。でも、時々「このオブジェクト、ちょっとだけ形を変えたいんだよな〜」って思うこと、ない?
例えば、ユーザー情報を管理してるとする。最初は全部必須項目だったのに、ある機能では「メールアドレスは任意でいいや」とか、「パスワードは今回は表示しなくていい」なんて場面が出てくる。そのたびに、いちいち新しい型定義を作るのは、正直ちょっと面倒くさい。
そこで登場するのが、今日の主役!TypeScriptが用意してくれた、まるで魔法の杖みたいな「組み込みユーティリティ型」たちなんだ!
今回は、この魔法の杖の中でも、特に「オブジェクトの型を変換する」のに大活躍する、
- `Partial
` - `Required
` - `Pick
` - `Omit
`
この4つにクローズアップして、その仕組みと、どうやって使えばみんなのコードがもっとスッキリ、そして賢くなるのかを、とーっても優しく、そして分かりやすく解説していくよ!
「型?なんか難しそう…」って思ってるあなたも大丈夫!身近な例え話をたくさん使いながら、一緒にTypeScriptの奥深い世界を覗いていこう!
—
0. まずは基本の「型」をおさらい!
ユーティリティ型のお話に入る前に、ちょこっとだけ基本の「型」について確認しておこう。まるで、料理の前に材料を準備するみたいにね!
- `boolean`: 「はい」か「いいえ」の二択。真偽値ってやつだね。
- `number`: 数字。整数も小数も、全部おまかせ。
- `string`: 文字列。文章とか、名前とか。
- `array`: 同じ種類のものがたくさん並んだもの。例えば、数字のリストとか、文字列のリスト。
- `tuple`: 「これは1番目が文字列で、2番目が数字!」みたいに、順番と型が決まってるリスト。ちょっと特殊だけど便利!
- `any`: 「なんでもこい!」な型。便利だけど、型チェックをすり抜けちゃうから、使いすぎには注意が必要だよ。
- `unknown`: 「なんでも入るけど、使う前にちゃんと調べてね!」な型。`any`より安全で、型を意識させる優等生。
これらの基本の型を組み合わせることで、複雑なデータ構造を表現できるんだけど、今回注目するのは「オブジェクト」の型なんだ。
オブジェクトって、どんなもの?
オブジェクトは、身の回りの「モノ」を表現するのにぴったり。例えば、こんな「人」の情報を考えてみよう。
interface Person {
name: string; // 名前(文字列)
age: number; // 年齢(数値)
isStudent: boolean; // 学生かどうか(真偽値)
email?: string; // メールアドレス(文字列、?は任意)
}
この`Person`型は、名前、年齢、学生かどうか、そして任意でメールアドレスを持っている、という情報を定義している。
さて、この`Person`型を元に、ちょっとした「型変換」の魔法を使ってみよう!
—
1. `Partial`: 「全部任意」にしちゃう魔法!
どんな時に使うの? ~お買い物シミュレーション~
想像してみて。あなたは今、お洋服屋さんで、欲しい服をいくつかピックアップしてる。
- ジャケット: 絶対に欲しい!
- パンツ: これも欲しい!
- シャツ: うーん、迷ってるけど、もしあれば買おうかな…
- ネクタイ: 別になくてもいいや。
こんな風に、いくつかのお洋服(プロパティ)があって、そのうち「必須」のものと「任意」のものがあるよね。
TypeScriptで、最初は「全部必須」で定義したオブジェクト型(例えば、ECサイトの「商品登録フォーム」の元型)があったとする。でも、後から「商品の更新機能」を作るときに、「商品名だけは必須だけど、説明文や画像は後からでもいいよ」みたいな、一部のプロパティを「任意」にしたい場面って結構あるんだ。
そんな時、`Partial
`Partial
魔法の仕組みを見てみよう!
例えば、さっきの`Person`型を`Partial`で加工してみよう。
// Partial
type PartialPerson = Partial
/
PartialPerson の型は、実際にはこんな感じになるイメージだよ:
{
name?: string;
age?: number;
isStudent?: boolean;
email?: string; // 元々任意だったemailも、そのまま任意だよ
}
/
// 実際に使ってみよう!
const partialUser: PartialPerson = {
name: “山田太郎”,
// ageやisStudent、emailは指定しなくてもOK!
};
console.log(partialUser); // { name: ‘山田太郎’ }
どう? `name`だけ指定して、`age`や`isStudent`、`email`は指定しなくてもエラーにならないのが分かるかな? まるで、さっきのお洋服選びで「シャツ」や「ネクタイ」を「今回は買わない」って決めても、お店に並んでる他の商品(ジャケットやパンツ)はそのまま買える、みたいな感じだよね!
「あー、なるほど!全部必須だった型を、一時的に『全部任意』にしたい時に便利なんだな!」 って思ってくれたら大正解!
—
2. `Required`: 「全部必須」にしちゃう魔法!
どんな時に使うの? ~プロフィール設定の最終確認~
今度は逆のケース。例えば、ユーザーがプロフィールを設定している場面を想像してみて。最初は「ニックネームは任意、電話番号も任意…」みたいに、ゆるめに設定していたとする。
でも、いざ「プロフィールを公開します!」ってボタンを押す前に、「あ、これ、公開するには全部の情報が埋まってないとダメだ!」ってなること、あるよね?
`Required
魔法の仕組みを見てみよう!
さっきの`PartialPerson`型を、今度は`Required`で加工してみよう。
// PartialPerson の型は、name?: string, age?: number, … だったね
// Required
type RequiredPartialPerson = Required
/
RequiredPartialPerson の型は、実際にはこんな感じになるイメージだよ:
{
name: string;
age: number;
isStudent: boolean;
email: string; // 元々任意だったemailも、これで必須になる!
}
/
// 実際に使ってみよう!
// 以下のコードはエラーになるはずだよ。なぜなら、emailが必須だから!
/
const fullyRequiredUser: RequiredPartialPerson = {
name: “山田太郎”,
age: 30,
isStudent: false,
// email を指定しないとエラー!
};
/
// 正しく指定すればOK!
const fullyRequiredUser: RequiredPartialPerson = {
name: “山田太郎”,
age: 30,
isStudent: false,
email: “taro.yamada@example.com”,
};
console.log(fullyRequiredUser); // { name: ‘山田太郎’, age: 30, isStudent: false, email: ‘taro.yamada@example.com’ }
どうかな? `Required`を使うと、たとえ元々任意だったプロパティ(`email`)も、強制的に必須になるのが分かるよね。まるで、プロフィール公開前に「住所と氏名、両方書いてくださいね!」ってチェックされるみたいだ!
「なるほど!任意だらけの型を、一時的に『全部必須』にしたい時に使えるんだね!」 って理解できたら、君もユーティリティ型の達人への道まっしぐらだよ!
—
3. `Pick`: 「欲しいものだけ、つまみ食い」する魔法!
どんな時に使うの? ~レシートの「欲しい情報だけ」抜き出し~
お買い物を終えて、レシートを受け取ったとする。レシートには、お店の名前、住所、電話番号、購入日時、商品名、単価、数量、合計金額… と、たくさんの情報が載ってるよね。
でも、あなたが欲しいのは、せいぜい「買ったもの」と「合計金額」くらい。お店の住所なんて、どうでもいい場合が多い。
`Pick
「つまみ食い」って言ったけど、まさにそんなイメージ! 欲しいものだけ、チョイスして持っていく感じ。
魔法の仕組みを見てみよう!
さあ、もう一度`Person`型を見てみよう。
interface Person {
name: string;
age: number;
isStudent: boolean;
email?: string;
}
この`Person`型から、「名前 (`name`)」と「年齢 (`age`)」だけを抜き出した新しい型を作ってみよう。
// Pick
type NameAndAge = Pick
/
NameAndAge の型は、実際にはこんな感じになるイメージだよ:
{
name: string;
age: number;
}
/
// 実際に使ってみよう!
const basicInfo: NameAndAge = {
name: “佐藤花子”,
age: 25,
// isStudent や email は指定できない!エラーになるよ。
};
console.log(basicInfo); // { name: ‘佐藤花子’, age: 25 }
// こんな風に、Pickで指定していないプロパティを指定しようとするとエラーになる
/
const errorInfo: NameAndAge = {
name: “佐藤花子”,
age: 25,
isStudent: true, // エラー! Person型から ‘isStudent’ は Pick されていないから。
};
/
どうかな? `Pick`を使うと、元の型から必要な部分だけを「つまみ食い」できるのが分かるよね。レシートから欲しい情報だけを書き写すみたいに、シンプルで分かりやすい!
「へぇ〜!元の型から、必要なプロパティだけを選んで使えるんだ!これは便利!」 って思ってくれたら、君のコードもきっとスッキリするはずだよ!
—
4. `Omit`: 「余計なもの、全部取り除いちゃえ!」魔法!
どんな時に使うの? ~SNSプロフィールから「公開したくない情報」を隠す~
SNSのプロフィールを想像してみて。あなたは、自分の名前、ニックネーム、自己紹介文、好きなもの… いろんな情報を登録してる。
でも、ある時「このプロフィールを、友達限定で公開しよう!」って思ったとする。その時、「友達には、生年月日や電話番号は知られたくないな…」って、公開したくない情報があるかもしれない。
`Omit
「Omit」は「省略する」「除外する」っていう意味。まさに、余計なものを「オミット」しちゃうイメージだね!
魔法の仕組みを見てみよう!
またまた`Person`型で試してみよう。
interface Person {
name: string;
age: number;
isStudent: boolean;
email?: string;
}
今度は、`Person`型から、「メールアドレス (`email`)」と「学生かどうか (`isStudent`)」を除外した、新しい型を作ってみよう。
// Omit
type PublicProfile = Omit
/
PublicProfile の型は、実際にはこんな感じになるイメージだよ:
{
name: string;
age: number;
}
/
// 実際に使ってみよう!
const publicInfo: PublicProfile = {
name: “田中一郎”,
age: 40,
// isStudent や email は指定できない!エラーになるよ。
};
console.log(publicInfo); // { name: ‘田中一郎’, age: 40 }
// こんな風に、Omitで除外したプロパティを指定しようとするとエラーになる
/
const errorProfile: PublicProfile = {
name: “田中一郎”,
age: 40,
email: “ichiro.tanaka@example.com”, // エラー! Person型から ‘email’ は Omit されているから。
};
/
どうかな? `Omit`を使うと、元の型から「これは見せたくない!」っていうプロパティを上手く除外できるのが分かるよね。SNSで、友達に見せたくない情報を隠すみたいに、プライバシーを守るのに役立つんだ!
「なるほど!不要なプロパティを『消して』、必要なものだけ残すことができるんだ!これは、データの使い分けにすごく便利!」 って思ってくれたら嬉しいな!
—
5. まとめ:ユーティリティ型で、TypeScriptをもっと自由に!
さあ、今日はTypeScriptの強力な味方、組み込みユーティリティ型の中から、
- `Partial
`: 全てのプロパティを任意にする - `Required
`: 全てのプロパティを必須にする - `Pick
`: 指定したプロパティだけを抜き出す - `Omit
`: 指定したプロパティだけを除外する
この4つを見てきたね!
これらのユーティリティ型を使いこなせるようになると、
- コードがスッキリする!: 同じような型定義を何度も書く必要がなくなる。
- 保守性が高まる!: 元の型が変わっても、ユーティリティ型で変換された型も自動的に追従してくれる。
- 柔軟な型設計ができる!: 状況に応じて、オブジェクトの型を自在に変化させられる。
まるで、料理で使う包丁やフライパンみたいに、TypeScriptの「型」を扱うための便利な道具なんだ。
最初はちょっと戸惑うかもしれないけど、色々な場面で意識して使ってみると、きっと「なるほど!」って思える瞬間が訪れるはず。
「あれ?この型、ちょっと変えたいな…」って思った時、まずはこれらのユーティリティ型でできないか考えてみてほしい。きっと、みんなのTypeScriptライフが、もっともっと豊かで、楽しくなるはずだよ!
これからも、TypeScriptの「なるほど!」を一緒に探求していこうね!またねー!👋

コメント