こんにちは!TypeScriptの世界へようこそ。チーフアーキテクトの私です。
TypeScriptを書き始めると、「string」や「number」といった基本の型から、少しずつ「型、なんだか難しくなってきたぞ……?」という壁にぶつかる瞬間がありますよね。特に、クラス(Class)や「コンストラクタ」という言葉が出てくると、途端にコードが難解に感じられて、そっとエディタを閉じたくなる気持ち、痛いほどよく分かります。
大丈夫ですよ、安心してください。今日はそのモヤモヤをスッキリ解消するために、`InstanceType
身近な例え話をたっぷり交えながら、一緒に紐解いていきましょう!
—
1. クラスって「設計図」、インスタンスは「そこから作られた実物」
まずは、`InstanceType
皆さんは、街で見かける「自動販売機」を思い浮かべてみてください。
あの頑丈な金属の箱を何台も並べて作るために、メーカーには「自動販売機の設計図」がありますよね。
- クラス(Class) = 自動販売機の「設計図」
- インスタンス(Instance) = その設計図通りに工場で作られて、実際に街角に置かれた「本物の自動販売機」
TypeScriptでコードを書くとき、私たちはよく「設計図(クラス)」を用意して、そこから「実物(インスタンス)」を作ります。
// 自動販売機の「設計図(クラス)」
class VendingMachine {
// 中に入っているジュースの数
juiceCount: number = 10;
// ボタンを押してジュースを買う機能
buyJuice() {
console.log(“ガチャン!ジュースが出てきました。”);
}
}
// 設計図から、実物(インスタンス)を「new」という合言葉で作る!
const myMachine = new VendingMachine();
ここで、`myMachine` という変数には、「設計図(VendingMachine)をもとに作られた実物」が入っています。この実物の型を、TypeScriptはちゃんと自動で察知してくれます。ここまでは何てことないですよね。
—
2. 「設計図そのもの」を渡されたとき、どう困る?
さて、ここからが本題です。
もし、誰かから「この設計図(クラスそのもの)をあげるから、ここから作られる実物の型を教えて!」と言われたら、どうでしょう?
ちょっとややこしい話をしますね。TypeScriptにおいて、「設計図そのもの(クラスのコンストラクタ)」を表す型は、実物の型とは違います。
// VendingMachineという「設計図そのもの」を表す型は、こう書きます
let MachineConstructor: typeof VendingMachine = VendingMachine;
「あれ? `VendingMachine` って書けばいいんじゃないの?」と思った方、大正解です。通常はそこまで意識しなくても動いてくれます。
しかし、「関数にクラスの設計図をポンと渡して、その中でうまいことインスタンスを操作したい」という、ちょっと高度なことをやろうとすると話が変わってきます。設計図そのものの型 (`typeof VendingMachine`) と、実物の型 (`VendingMachine`) は別物なので、「この設計図から生まれる実物の型って、一体なんだっけ?」とTypeScriptが迷子になってしまうことがあるんです。
そんなとき、「この設計図を渡すから、そこから生まれる実物の型を教えてちょうだい!」とTypeScriptにお願いできる魔法のアイテムが、`InstanceType
—
3. InstanceType って、なにをしてくれるの?
`InstanceType
英語のニュアンスそのままなのですが、こう読んでみてください。
> 「InstanceType(インスタンスの型を)
お買い物に例えるなら、「カタログ(設計図)の表紙を見せるだけで、倉庫からその製品の実物(インスタンス)を取り出して見せてくれる自動お取り寄せシステム」のようなものです。
百聞は一見に如かず。実際にコードを見てみましょう。
// 1. まずは普通のクラス(設計図)を用意
class Dog {
bark() {
console.log(“ワン!”);
}
}
// 2. 「Dogの設計図そのもの」を型として変数に入れます
type DogConstructor = typeof Dog;
// 3. ここで登場するのが InstanceType
// 「DogConstructor(設計図)から生まれる実物の型って何?」と聞いています。
type MyDogInstance = InstanceType
// 結果として、 MyDogInstance は 「Dog」 という実物の型と同じ意味になります!
const pochi: MyDogInstance = new Dog(); // バッチリ型が合います!
pochi.bark(); // 「ワン!」
「おぉ……なんだかカッコいいけど、これっていつ使うの?」と思いましたか?
そうですね、普段のアプリ開発で、自分で書いたクラスをその場で `new` するだけなら、実はあまり使いません。
真価を発揮するのは、「動的にクラスを受け取る関数」を書くときです。
—
4. 実戦投入!動的にクラスを扱う関数を作ってみよう
例えば、「どんなクラスの設計図でも受け取って、それを新しく画面に生み出す(インスタンス化する)工場のような関数」を作りたいとします。
こんな時、`InstanceType
// 従業員を表すクラス
class Employee {
constructor(public name: string) {}
}
// ロボットを表すクラス
class Robot {
constructor(public serialNumber: string) {}
}
/
- 【工場の関数】
- どんな「設計図(T)」を受け取っても、
- InstanceType
を使って「正しい実物の型」を返り値の型として保証する!
/
function createInstance
ctor: T
): InstanceType
// ※複雑に見えますが、「どんな引数でも受け取れるコンストラクタ」という意味です
// 実際に new して返す
// (※ここでは分かりやすくするため、簡易的に any でキャストしています)
return new ctor(“適当なデータ”) as InstanceType
}
// さあ、使ってみましょう!
// Employeeの設計図を渡すと……
const worker = createInstance(Employee);
// worker の型は、自動的に 「Employee」 になります!
console.log(worker.name); // 「適当なデータ」
// Robotの設計図を渡すと……
const android = createInstance(Robot);
// android の型は、自動的に 「Robot」 になります!
console.log(android.serialNumber); // 「適当なデータ」
お疲れ様でした!少し難しい構文 (`new (…args: any[]) => any` など) も出てきましたが、一番大切なポイントはそこではありません。
> 「クラスの設計図(コンストラクタ)を引数で受け取るような汎用的なコードを書くとき、そこから作られる実物の型を知りたければ `InstanceType
これさえ心に留めておいてもらえれば、100点満点です!
—
まとめ:つまずいたときは「設計図と実物」を思い出して
TypeScriptの高度な型機能は、最初は呪文のように見えて心が折れそうになりますよね。「なんでこんな面倒なことしなきゃいけないんだろう」と思うこともあるでしょう。
でも、それはTypeScriptが「あなたの書いたコードの安全性を、一生懸命後ろから支えようとしてくれているから」なんです。
- クラスは「設計図」
- インスタンスは「実物」
- `InstanceType
` は、設計図から実物の型を引っ張り出す「お取り寄せボタン」
このイメージさえ持っておけば、今後もっと複雑なライブラリのコードや、フレームワークの内部構造を読むときにも、きっと「あ、あのときの仕組みだな」とスッと理解できるようになります。
一歩ずつ、自分のペースでTypeScriptと仲良くなっていきましょう。あなたの開発ライフが少しでも楽しく、快適になりますように!チーフアーキテクトの私でした。また次回の記事でお会いしましょう!

コメント