どうしてもVue.jsが分からないので森の博士の研究所に押しかけてみたら、人生が激変した子タヌキの話
frontendBabyのテックブログで公開している連載の一部になります。
注
この物語は、フロントエンド技術を楽しく学ぶことを目的に、生成AIを活用して執筆されています。
技術的な情報の正確性には細心の注意を払っていますが、その内容がすべて真実であることを保証するものではありません。
あくまで学習の補助ツールとして、肩の力を抜いてお楽しみください。
登場人物紹介
- フロントエンド博士: 森の奥の研究所に住む、フロントエンドのことなら何でも知っている物知り博士。ポン吉の素朴な疑問にいつも優しく(そして面白おかしく)答えてくれる。
- ポン吉: 好奇心旺盛な子タヌキ。将来の夢はフロントエンドエンジニア。最近Vue.jsを学び始めたが、その奥深さに興味津々。新しい知識をゲットすると、思わず「ポン!」と飛び跳ねる特技あり。
第6話🦝「createAppの型を見てみよう」
TypeScriptという新しい魔法の地図を手に入れたポン吉。今日はどんな発見があるのかと、ワクワクしながら研究所の扉を叩いた。
ポン吉: 「博士、こんにちは!TypeScript、すごく面白いです!ポン!」
博士: 「おお、ポン吉。その意気や良し。今日は、いつも使っているcreateApp
関数が、TypeScriptの世界でどんな姿をしているのか、一緒に見てみようじゃないか。」
博士はモニターに、Vue.jsのライブラリの中にある「型定義ファイル」というものを表示した。
ポン吉: 「型定義ファイル...?」
博士: 「うむ。TypeScriptのために、『このライブラリに含まれる関数やオブジェクトは、こういう形(型)をしていますよ』という情報が書かれた、いわば設計図のようなファイルじゃ。」
そこに書かれていたのは、見慣れない記号で書かれたcreateApp
の姿だった。
export declare function createApp<HostElement = Element>(
rootComponent: Component,
rootProps?: Data | null
): App<HostElement>
ポン吉: 「うわわ...!これがcreateApp
なんですか!?なんだか、呪文みたいです...」
博士: 「はっはっは。確かに、初めて見ると面食らうかもしれんな。じゃが、一つ一つ見ていけば、決して難しいものではないんじゃよ。」
博士はコードの一部分を指差した。
博士: 「まず、function createApp(...)
とあるから、これが関数であることは分かるな?」
ポン吉: 「はい!それは分かります!」
博士: 「次に、(...)
の中身、つまり引数を見てみよう。rootComponent: Component
と書いてある。」
ポン吉: 「:
(コロン)が付いてる...!これ、昨日のa: number
と同じですね!つまり、rootComponent
という引数の型は、Component
なんですね!」
博士: 「その通り!素晴らしいぞ、ポン吉!我々がいつもcreateApp
の最初の引数に渡しているオブジェクトは、Vueの世界ではComponent
という型として扱われておるんじゃ。」
ポン吉: 「なるほどー!じゃあ、その隣のrootProps?: Data | null
っていうのは...?」
博士: 「?
は、『この引数はあってもなくても良いですよ』という意味の印じゃ。そして|
は、『または』という意味。つまり、rootProps
という引数は、Data
型、またはnull
、または何もなくても良い、ということになる。」
ポン吉: 「ふむふむ。引数にも、色々なルールがあるんですね。」
博士: 「そして、一番面白いのがここじゃ。」
博士は、<HostElement = Element>
と、戻り値の: App<HostElement>
という部分を指した。
博士: 「この<...>
という記号、これを『ジェネリクス』と呼ぶ。これは、型を引数のように渡せる、TypeScriptの非常に強力な魔法なんじゃ。」
ポン吉: 「ジェネリクス...?型を引数に...?」
博士: 「今は『色々な型に対応できる、柔軟な型を作るための仕組み』くらいに思っておけば大丈夫じゃ。例えば、App<HostElement>
というのは、『HostElement
という型によって、中身が少し変わるApp
という型』を返す、という意味なんじゃよ。」
ポン吉は少し混乱したが、createApp
という馴染みのある関数が、TypeScriptの世界では、引数や戻り値に厳密なルール(型)を持った、しっかりとした設計図に基づいて作られていることに、深く感動した。
ポン吉: 「すごい...!僕が何気なく使っていたcreateApp
は、こんなにしっかりとした型で守られていたんですね!だから、間違った使い方をすると、TypeScriptが怒ってくれるんだ!」
博士: 「その通りじゃ!この型定義があるおかげで、我々はcreateApp
を安全に、そして正しく使うことができるんじゃよ。」
ポン吉: 「博士、もっと知りたいです!このComponent
っていう型は、一体どんな形をしているんですか?」
ポン吉の探求心は、ますます燃え上がっていた。
博士: 「うむ!良い質問じゃな。では次回は、そのComponent
型の秘密を解き明かしてみることにしよう。」
ポン吉: 「はい!楽しみです!ポン!」
🌟 今日のまとめ
- TypeScriptの世界では、ライブラリの関数やオブジェクトの形が 型定義ファイル に書かれている。
-
createApp
も、引数と戻り値に厳密な 型 が付けられている。 -
rootComponent: Component
のように、:
(コロン)を使って引数の型を指定する。 -
?
は「省略可能」、|
は「または」を意味する。 -
<...>
(ジェネリクス) は、型をより柔軟にするための強力な仕組み。
次回予告 「Component型って何だろう?」
createApp
に渡す、おなじみのコンポーネントオブジェクト。その正体であるComponent
型とは、一体どんな構造になっているのでしょうか?ポン吉と一緒に、その中身をのぞいてみましょう!
👨🏫 博士からの補足
今日の話では、我々は node_modules
という深い森に分け入って、Vueの型定義ファイル(.d.ts
ファイル)を覗いてみたのじゃ。
ポン吉は、あの中に書かれていたのがただのテキストファイルではないことに気づいたかの? あれは「型定義ファイル」といって、TypeScriptに「この関数はこういう引数を取って、こういう値を返すんじゃよ」と教えるための、いわば「設計図」や「地図」のようなものなんじゃ。
このファイルがあるおかげで、我々がコードを書くときにエディタが賢く補完してくれたり、間違いを未然に防いでくれたりするんじゃな。
そして、一つ大事な約束じゃ。node_modules
の森は、パッケージマネージャ(npmやyarn, bunなど)が管理する聖域じゃ。我々は中を覗いて学ぶことはあっても、決して中のファイルを直接編集してはいかんぞ。
「もし編集したら、次にパッケージをインストールした時に元に戻っちゃうから?」と疑問に思うかもしれん。それも理由の一つじゃが、もっと大切な理由があるんじゃよ。
一番の理由は、**「誰がやっても同じ環境を再現できなくなる」**からじゃ。もしポン吉が自分のパソコンでだけファイルを書き換えてしまうと、他の人のパソコンや、アプリを公開するサーバーとは違う、ポン吉だけの特別な環境が出来上がってしまう。これは「自分のパソコンでは動くのに、他の場所では動かない」という、とても困った問題の原因になるんじゃ。
それに、node_modules
はGitで管理されていないからの、ポン吉が加えた変更は記録に残らず、他の誰にも共有されない。まさに「その場しのぎ」になってしまうんじゃな。
だから、node_modules
は自分で書き換える『ソースコード』ではなく、『読み取り専用の図書館』のようなものだと覚えておくんじゃ。今は「そんなものがあるんだな」くらいに思っておいてくれれば十分じゃ。いつかポン吉が自分だけのライブラリを作る時が来たら、この型定義ファイルのありがたみが、もっとよく分かるはずじゃよ。
第6話 おわり