こんにちは!TypeScriptの学習、毎日お疲れ様です。
型定義の基本を一通り覚えて、「よし、これからバリバリコードを書くぞ!」と意気込んだ矢先に見慣れない記号や、ちょっと難しそうなユーティリティ型にぶつかって、「うっ……」と手が止まってしまうこと、ありませんか?大丈夫ですよ、その壁は誰もが通る道です。
今回は、そんなTypeScriptの組み込み型の中から、ちょっぴり名前が強そうな`OmitThisParameter
「関数型からthisパラメータを除去する?」
なんだか呪文のようですが、身近な例えを交えながら、一緒に優しくほどいていきましょう!
—
そもそも、関数の中の `this` ってなんだっけ?
JavaScriptやTypeScriptを書いていると、時々 `this` というキーワードに出会いますよね。「この関数が今、誰に呼ばれているか」を指し示す、いわば名札のようなものです。
例えば、こんなオブジェクトとメソッドがあったとします。
const counter = {
count: 0,
// ここでの this は counter オブジェクト自身を指します
increment() {
this.count++;
}
};
JavaScriptの世界では、この `this` が曲者で、関数を別の場所にポンと渡したりすると、「あれ? 私の `this`、どこに行った!?」と迷子になってしまうことがよくあります。そのため、TypeScriptの関数では、「この関数を使うときは、絶対にこの `this` をセットで渡してね!」と、関数の最初の引数の場所にこっそり `this` の型を明記することがあるんです。
例え話:背負いリュックを背負った関数
イメージしてみてください。
普通の関数が「身軽なTシャツ姿のランナー」だとすると、`this` を持っている関数は、「大きな背負いリュック(thisのルール)を背負ったランナー」です。
このリュックは、特定の競技(オブジェクトのメソッドとして使うなど)ではすごく便利なんですが、「ちょっとそのリュックを下ろして、純粋に走るだけのレースに出てよ!」という場面が、フロントエンド開発では時々やってきます。
そんなとき、「その背負いリュック(this)をスポッと脱ぎ捨てて、身軽な状態の関数に作り替えてくれる」のが、今回主役の `OmitThisParameter
—
`OmitThisParameter` の基本的な使い方
百聞は一見にしかず。コードを見てみましょう。
// thisの型(リュック)を明示的に持っている関数型を用意します
// 意味:「この関数は、thisとして { prefix: string } を受け取る前提だよ」
function greet(this: { prefix: string }, name: string) {
return `${this.prefix}、${name}さん!`;
}
// この時点での greet 関数の型は、thisのリュックを背負っています。
// さて、ここに OmitThisParameter を使ってみましょう!
type GreetWithoutThis = OmitThisParameter
// 【結果どうなる?】
// GreetWithoutThis の型は、以下のように変換されます:
// (name: string) => string
// 見事に this の指定が消え去り、普通の関数型になりました!
すごいですね! `OmitThisParameter
—
どんなときに使うの?(実務でのリアルなユースケース)
「へえ、thisを消せるんだ。でも、それっていつ使うの?」って思いますよね。
一番よくあるのは、「ライブラリから渡ってきた、this前提のメソッドを、純粋なコールバック関数として別の場所に登録したいとき」などです。
例えば、ReactやVueなどのUIライブラリ、あるいは古き良きDOMのイベントリスナーなどを触っていると、「あれ、この関数、なんかthisのせいで型エラーになるぞ……?」という現象に出くわします。そんな時、このユーティリティ型を知っていると、「あ、ここでリュックを下ろしてあげればいいんだな!」とスマートに解決できるようになります。
ちょっと実践的なサンプルを見てみましょう。
// ボタンのクリックイベントをハンドリングするクラスのメソッドだと想像してください
class ClickHandler {
constructor(private message: string) {}
// this を使っているメソッド
handleClick(this: ClickHandler, event: Event) {
console.log(this.message, event);
}
}
const handler = new ClickHandler(‘こんにちは!’);
// 通常、handler.handleClick をそのまま別の関数にポンと渡すと、
// 「thisの文脈が消えちゃったよ!」とTypeScript怒られてしまいます。
// そこで、あらかじめ this なしの型として扱いたい場面が出てきます。
// OmitThisParameter を使って、thisなしの「純粋な関数型」として型を保証する
type PureClickHandler = OmitThisParameter
// 型が (event: Event) => void になっているので、
// this を気にせず安全にコールバックとして扱えるようになります!
「うわ、ちょっと難しくなってきたな……」と感じた方、大丈夫です! 今すぐこのコードの細かい仕組みを完璧に理解しなくても全く問題ありません。「あ、thisっていう面倒な縛りを解除したいときに、こういう便利な型のお医者さんツールがあるんだな」と心の片隅に置いておいてもらうだけで十分100点満点です。
—
まとめ:つまずいたときは「身軽にしよう」と思い出そう
今回は、TypeScriptの `OmitThisParameter
- what(とは?): 関数型から `this` のパラメータ(リュック)を取り除いて、扱いやすい形に変換してくれるユーティリティ型。
- why(なぜ?): `this` の縛りがあるせいで他の場所で使いにくい関数を、プレーン(素直)な関数型に生まれ変わらせるため。
TypeScriptのこういったユーティリティ型は、最初は呪文のように見えて尻込みしてしまいますが、一つひとつの役割を「身の回りの道具や例え」に置き換えてみると、案すんなり頭に入ってきます。
もし今後、コード書いていて `this` 周りの型エラーに遭遇して頭を抱えたときは、「あ、そういえばあいつ(OmitThisParameter)がリュックを下ろしてくれたっけな」と、この記事を思い出していただけたら嬉しいです。
あなたのTypeScriptの旅が、少しでも軽やかで楽しいものになりますように。それではまた!

コメント