【入門編】 インターフェースの継承(extends) – TypeScript実践ガイド

こんにちは!TypeScriptの世界へようこそ。チーフアーキテクトの私です。

TypeScriptを触り始めたばかりの頃って、次から次へと新しい専門用語が出てきて、「うっ…頭が痛い…」ってなりますよね。特に型定義のルールなんて見ているだけで眠くなっちゃうこともあるでしょう。でも、大丈夫ですよ。一つひとつ、身近なものに例えて紐解いていけば、決して難しいものではありません。

今回は、そんなTypeScriptの基本の中でも、実務でめちゃくちゃよく使う「インターフェースの継承(`extends`)」について、おしゃべりするみたいに優しく解説していきますね。

—

1. 「継承(extends)」ってなに? 身近な例えで考えてみよう

いきなりコードを書く前に、まずはイメージを掴みましょう。

「継承」という言葉、なんだか難しそうですが、要は「ベース(基本)の機能を受け継ぎつつ、新しい機能を追加すること」です。

身の回りのもので例えてみましょう。そうだな、「スマートフォン」で考えてみましょうか。

世の中には「普通のスマホ」という基本形がありますよね。画面があって、カメラがあって、電話ができる。
でも最近は、そこに「防水機能」が追加された「防水スマホ」や、さらに「おサイフケータイ機能」が追加された「おサイフ対応スマホ」がありますよね。

これをプログラミング風に言うと、

  • 普通のスマホ:「画面」「カメラ」「電話」を持つ基本の型
  • 防水スマホ:普通のスマホの機能をすべて持った上で、さらに「防水レベル」という新しい機能が追加された型

この「基本の型をベースにして、新しいパワーを付け足す仕組み」こそが、TypeScriptの `extends`(引き継ぐ)なんです。

—

2. なぜ `extends` を使うの?(コピペ地獄からの脱出)

もし、この `extends` を使わなかったらどうなると思いますか?

例えば、Webサイトのユーザーデータを管理するアプリを作っているとします。
「一般ユーザー」と「プレミアム会員」という2つのデータ型を作りたいとき、もし `extends` を知らないと、こんな風に書いちゃうんです。

// 一般ユーザーの型
interface NormalUser {
id: string;
name: string;
email: string;
}

// プレミアム会員の型(あれ、idもnameもemailも、さっきと同じものをもう一回書いてる…?)
interface PremiumUser {
id: string;
name: string;
email: string;
point: number; // プレミアム会員だけの特典ポイント
couponRate: number; // 割引率
}

お気づきでしょうか? `id` や `name`、`email` が完全に被っていますよね。
もし後から「やっぱり年齢(`age`)の項目も追加しよ!」となったら、両方の型を書き直さないといけません。これじゃあコードがメンテナンスしづらくて、現場のエンジニアなら泣いちゃいます。

そこで登場するのが、`extends` キーワードです!

—

3. `extends` を使った書き方を見てみよう

実際にコードを書いてみましょう。先ほどのユーザーの例を、`extends` を使ってスマートに書き直してみますね。

// 1. まずはすべての基本となる「ベースの型」を作る
interface BaseUser {
id: string;
name: string;
email: string;
}

// 2. BaseUserを「継承(extends)」して、プレミアム会員の型を作る
// 「BaseUserが持っているプロンプトを全部ください!その上で、こっちの新しい項目も追加します!」という意味になります
interface PremiumUser extends BaseUser {
point: number; // プレミアム会員だけの特典ポイント
couponRate: number; // 割引率
}

// — 実際に使ってみる —

// プレミアム会員のオブジェクトを作ってみるよ
const tanaka: PremiumUser = {
id: “u-001”,
name: “田中 太郎”,
email: “tanaka@example.com”,
point: 1200, // PremiumUser独自のプロパティ
couponRate: 0.1, // PremiumUser独自のプロパティ
};

console.log(tanaka.name); // 問題なく「田中 太郎」が表示されます!

どうでしょう? `extends BaseUser` と書くだけで、`id` や `name`、`email` をわざわざもう一度書く必要がなくなりました。
もし今後、全ユーザーに共通する項目が増えたとしても、大元の `BaseUser` だけを直せばいいので、コードがすっきりと美しく保てます。

—

4. つまずきやすいポイント:あの子とこの子の違い

初心者の方がよく混乱するポイントをこっそりシェアしておきますね。

「えっ、オブジェクトの形をコピーするなら `&`(交差型)とも似てない?」

そうなんです。TypeScriptには `type` と `&`(インターセクション型)を使って、似たようなことを実現する方法もあります。

type BaseUser = { id: string; name: string; };
type PremiumUser = BaseUser & { point: number; };

「あれ、これじゃダメなの?」と思いますよね。動かすだけならほぼ同じ結果になります。
ただ、実務の現場では、「オブジェクトの型を拡張してきれいに管理したいときは `interface` と `extends` を使う」というスタイルが好まれることが多いです。エラーメッセージが人間にとって読みやすくなったり、TypeScriptのエディタ(VSCodeなど)が賢くサジェスト(候補表示)してくれるメリットがあるからなんですね。

最初は大人の事情はさておき、「オブジェクトの共通の土台を作るときは `extends` を使うと気持ちいいんだな」と覚えておけば100点満点です!

—

5. まとめ

いかがでしたでしょうか? 今回はインターフェースの継承(`extends`)についてお話ししました。

  • `extends` は、既存の型をベースにして新しい型を効率よく作れる便利な仕組み。
  • 同じようなプロパティを何度も書く「コピペ地獄」から救ってくれる。
  • コードのメンテナンス(修正)が圧倒的にラクになる。

最初は難しく感じるかもしれませんが、エディタにコードを打ち込んで、エラーが出たり消えたりするのを面白がりながら触っていくうちに、自然と手が覚えていきます。焦らず、あなたのペースで一歩ずつ進んでいきましょうね。

それでは、快適なTypeScriptライフを!

コメント

タイトルとURLをコピーしました