【入門編】 ThisParameterTypeによるthisの型抽出 – TypeScript実践ガイド

みなさん、こんにちは!
日夜、お仕事や趣味でコードを書いているみなさん、本当にお疲れ様です。

JavaScriptやTypeScriptを学び始めていると、いつか必ずぶつかる「壁」のような存在がありますよね。その代表格が、「`this`(ディス)」です。

「この `this` って、一体だれを指しているの?」
「コードを動かしてみたら、思っていたのと違う場所を指していてエラーになっちゃった……」

そんな経験はありませんか? 実は、現場で何年もコードを書いているプロのエンジニアでも、この `this` の扱いには何度も頭を悩まされているんです。ですから、今「よくわからないな」と思っていても、全く恥ずかしがる必要はありません。本当に大丈夫ですよ。

今回は、そんな迷子になりがちな `this` をTypeScriptの力で優しくコントロールし、「この関数は、どんなお部屋(コンテキスト)で使われるべきものなの?」という情報をきれいに抜き出してくれる便利ツール、`ThisParameterType` という魔法の道具について、お買い物の例え話も交えながら、世界一わかりやすく解説します。

リラックスして、温かいコーヒーでも飲みながら、一緒に一歩ずつ進んでいきましょう!

—

1. そもそも `this` ってなに?(身近な例え話)

まずは `this` のイメージを、私たちの身の回りにあるもので例えてみますね。

あなたが「マイバッグ(エコバッグ)」を持っていると想像してください。

  • スーパーのレジにいるとき、あなたが「これに商品を入れてください」と言ったら、その「これ(`this`)」はあなたが持っているマイバッグを指しますよね。
  • でも、もしあなたがお友達の家にいて、お友達が「これ片付けておいて」と言ったら、その「これ(`this`)」はテーブルの上のコップやゴミを指すかもしれません。

このように、「これ(`this`)」が何を指すかは、その言葉が「どんな場所(状況・コンテキスト)」で使われたかによって、コロコロと変わってしまいます。

プログラムの世界でも全く同じです。
関数(命令のまとまり)の中で `this` という言葉を使うとき、「この関数は、どんな場所で実行されるのか」によって、`this` の中身が変わってしまうのです。

—

2. TypeScriptで「私はこの場所で使われます」と宣言する

TypeScriptでは、関数に対して「私は、こういうお部屋(オブジェクト)の中で使われる関数ですよ!」とあらかじめ自己紹介しておくことができます。

やり方はとても簡単で、関数の最初の引数に `this: 型名` と書くだけです。

// お買い物カートの型(お部屋のルール)
type ShoppingCart = {
totalPrice: number; // 合計金額
};

// 割引を適用する関数(道具)
// 「私は ShoppingCart の中で使われる道具ですよ」と自己紹介しています
function applyDiscount(this: ShoppingCart, discount: number) {
// this は ShoppingCart のことなので、totalPrice にアクセスできます!
this.totalPrice -= discount;
}

関数のカッコの中の最初に `this: ShoppingCart` と書いてありますね。
これは、「この `applyDiscount` という関数は、`ShoppingCart` という型を持ったお部屋の中でしか使っちゃダメですよ」というルールを敷いているのです。

—

3. 本題:`ThisParameterType` ってなぁに?

ここで、今回の主役である `ThisParameterType` の登場です!

これは、一言でいうと「ある関数(T)の自己紹介カードから、`this` の型(=どんなお部屋で使われるべきか)だけをスポンと抜き出す便利ツール」です。

例えば、先ほどの `applyDiscount` という関数がありますよね。
「この関数が求めている `this` の型(お部屋のルール)って、なんだったっけ? 別の場所でもその型を使い回したいな」と思ったときに、この魔法のツールを使います。

視覚的なイメージ

  • 関数(applyDiscount): 「私は `ShoppingCart` の中で動きます! 割引額(`discount`)を受け取ります!」
  • `ThisParameterType` を使うと: 「ふむふむ、この関数は `ShoppingCart` の中で動くんだね。じゃあ、`ShoppingCart` という型だけを抜き出しておくよ!」

こうして、関数から `this` の型だけを取り出して、別の場所で再利用できるようになります。

—

4. 実際にコードを動かして体験してみよう!

それでは、実際にエディタに貼り付けて動かせるサンプルコードを見てみましょう。
コメントをたくさん入れたので、一行ずつゆっくり読んでみてくださいね。

// 1. まずは「お買い物カート」の型を定義します
type ShoppingCart = {
totalPrice: number;
items: string[];
};

// 2. カートの中身を表示する関数を作ります。
// 最初の引数に「this: ShoppingCart」と書くことで、
// 「この関数は ShoppingCart の中(コンテキスト)で実行してね」と制限しています。
function showCartSummary(this: ShoppingCart, taxRate: number): void {
const tax = this.totalPrice taxRate;
console.log(`カートの商品: ${this.items.join(‘, ‘)}`);
console.log(`消費税: ${tax}円 / 合計: ${this.totalPrice + tax}円`);
}

// ==========================================
// ★ ここで ThisParameterType の魔法を使います!
// ==========================================

// showCartSummary という関数が求めている「this の型」を自動で抜き出します。
// これにより、 `ExtractedCartType` は 「ShoppingCart」型 と全く同じになります!
type ExtractedCartType = ThisParameterType;

// 3. 抜き出した型を使って、新しいカートのデータを作ってみましょう。
// ExtractedCartType は ShoppingCart 型と同じなので、totalPrice と items が必要になります。
const myCart: ExtractedCartType = {
totalPrice: 3000,
items: [‘おいしいリンゴ’, ‘オーガニックバナナ’]
};

// 4. 関数を実行してみます。
// そのまま showCartSummary() と呼ぶのではなく、
// 「myCart の中でお仕事をしてね」と伝えるために .call() を使います。
showCartSummary.call(myCart, 0.1);
// 出力結果:
// カートの商品: おいしいリンゴ, オーガニックバナナ
// 消費税: 300円 / 合計: 3300円

なぜこれが嬉しいの?(現場のリアルな視点)

「最初から `ShoppingCart` って直接書けばいいじゃない?」と思うかもしれません。確かにその通りです!

しかし、実際の開発現場では、「他人が作ったライブラリの関数」や、「複雑に組み合わさって、直接型名が書かれていない関数」を扱うことがよくあります。

そのようなときに、「この関数が求めている `this` の型が何なのか、元のコードを書き換えることなく、外側からスマートに抜き出したい!」という状況が生まれます。そんなときに、この `ThisParameterType` が大活躍するのです。

—

5. つまずきやすいポイント(大丈夫、怖くありません)

もし `this` が定義されていない関数にこれを使ったらどうなる?

「もし、`this: 型名` と書かれていない普通の関数に対して `ThisParameterType` を使っちゃったら、壊れちゃうの?」と心配になりますよね。

安心してください。ちゃんと優しいセーフティネットがあります。

// this を指定していない、普通の関数
function sayHello(message: string) {
console.log(message);
}

// この関数から this の型を抜き出そうとすると…?
type SafeType = ThisParameterType;
// 結果は「unknown(何かわからないもの)」になります!

TypeScriptは、`this` の指定がない関数に対して `ThisParameterType` を使った場合、エラーで画面を真っ赤にするのではなく、`unknown` という「何者か特定できないけれど、安全な型」を返してくれます。

壊れることはないので、安心して色々な関数に試してみてくださいね。

—

まとめ:一歩ずつ、階段をのぼるように

今日覚えたことを、おさらいしてみましょう。

1. `this` は、関数が実行される「お部屋(コンテキスト)」のこと。
2. 関数の最初の引数に `this: 型` と書くことで、「このお部屋で使ってね」と縛ることができる。
3. `ThisParameterType` は、その関数が求めている「お部屋の型」を後からスポンと抜き出す魔法の道具。

最初は「なんでこんな型が必要なんだろう?」と思うかもしれませんが、自分で複雑なWebアプリを作ったり、便利なプラグインを設計したりするようになると、「あのとき学んだツールが使えるぞ!」とアハ体験のように繋がる瞬間が必ずやってきます。

焦らず、一歩ずつ進んでいきましょう。あなたのTypeScriptライフを、いつも応援しています!

コメント

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