こちらの記事で TypeScript を有効にした プロジェクト を作成しました。 今回は Vue3 プロジェクト に TypeScript コンポーネント を追加して 実際に Vue.js のなかで TypeScript を使っていきたいと思います。
macOS: 12.1 vue: 3.2.1 typeScript: 4.5.5
Vue3 における TypeScript コンポーネント 必須要素
TypeScript の コンポーネント とはいえ Vue.js の中では 素の JavaScript 同様に 拡張子 を vue として コンポーネント を作成していく形になります。 本記事では src / components ディレクトリ に TypeScriptSample.vue という ファイル を作成していきます。
vue ファイル に含める要素は JavaScript 同様に以下です。
- template タグ
- script タグ
- style タグ
JavaScript では template -> script -> style の順番で記載することが多かった印象ですが、 TypeScript では script -> template -> style と HelloWorld.vue 記載されています。 本 ブログ でもその形式で進めたいと思います。
なお スタイルガイド によると style タグ が最後であれば template と script の順番はどちらが先でもよく プロジェクト 内で一貫していれば良さそうです。
JavaScript と異なる点としては 以下の2点が挙げられます。
- script タグ に lang=”ts” を指定
- script タグ 内で defineComponent() を記載
それでは 少し詳細をみていきます。
script タグ に lang=”ts” を指定
“To use TypeScript in SFCs, add the lang=”ts” attribute to <script> tags. ”
script タグ では 公式 サイト に記載されている通り以下のように記載します。
<script lang="ts"></script>
script タグ 内で defineComponent() を記載
To let TypeScript properly infer types inside component options, we need to define components with defineComponent():
https://vuejs.org/guide/typescript/overview.html#definecomponent
TypeScript として コンポーネント を記載するためには、 以下のように script タグ 内で defineComponent を 記載する必要があります。 こうすることで 型推論 も有効になります。
とりあえず 先に進めるためには “おまじない” だと思って 以下を script タグ 内に記載すれば問題ありません。
import { defineComponent } from 'vue' export default defineComponent()
TypeScript 固有の約束事が理解できてきたところで TypeScript ならではの機能を コンポーネント に実装していきたいと思います。
型推論 (defineCompent) について
ここで少し 型推論 について補足しておきます。 型推論 とは 変数宣言時に 文字列型 や 数値型 という型を指定しなくても プログラミング 言語の内部としては プログラミング の文脈から 型を推測して 型を保持するというものです。 C 言語などでは変数宣言時に型の指定が必須でしたが、 JavaScript や TypeScript, Python などでは型の指定は必須ではないため 型推論 が必要になってきます。
TypeScript における 型推論 (Type Inference) については 以下の リンク を参考にしてみてください。
TypeScript ならではの機能を コンポーネント に実装
TypeScript ならではの機能にはいくつかありますが、ここでは Interfaces を取り上げたいと思います。
Interfaces
Interface とは 以下の例のように 型 を指定された 変数 をまとめて定義したものです。 ここでは 人名 (name: string 型) と 身長 (height: number 型) をまとめて 人 (Person) として定義しています。
interface Person { name: string height: number }
それでは、 この Person インターフェース を 画面上に表示するような実装をしていきたいと思います。
インターフェース を アプリケーション に表示するよう実装
今回は、 以下のように Person インターフェース の オブジェクト として david を作成し その内容を 表示するように実装してみます。
script タグ
script タグ には 以下のような内容を記載していきます。
- defineComponent を import
- interface Person を定義
- export default として defineComponent を指定
- defineComponent の中に data() を定義
- data() として Person インターフェース オブジェクト の david を return するようにする
import { defineComponent } from 'vue' interface Person { name: string height: number } export default defineComponent({ data() { return { david: { name: 'David Beckham', height: 180.1 } as Person } } })
template タグ
画面に表示する template 部分 は以下のように記載します。
- Person インターフェース の name を 姓名 で分割表示
- Person インターフェース の height を 小数点以下第二位 まで補完して表示
{{ david.name.split(' ')}} {{ david.height.toFixed(2) }}
実行結果
上記の内容で実行すると以下のような出力となります。
期待した通り、 性と名が分割表示され、 身長が 小数点以下まで表示していることが確認できます。
VSCode 上での 型 チェック
TypeScript で簡単な アプリケーション を作成することができましたが、 TypeScript の重要な特徴である 型 チェック についても確認していきたいと思います。
先ほどの template に記載した内容を以下のように変更してみます。本来 split メソッド は string 型に対してのみ有効なため number 型の height に対しては エラー となります。
{{ david.height.split(' ')}} {{ david.height.toFixed(2) }}
実際に試してみると、 記載を変更した瞬間に VSCode 上で 以下のように エラー が チェック され 通知してくれます。
JavaScript で同様の コード を記載して実行すると 上記のような 型 チェック はされないため エラー に気づかず ビルド して 実行 してしまうこともあり得ます。 当然、 実行後 ブラウザ の コンソール には以下のように エラー は表示されるのですが、 エラー の指摘は早ければ早い方が良いですよね。
まとめ
- TypeScript コンポーネント は 拡張子 vue で作成
- script タグ
- lang=”ts” を記載
- defineComponent を import し記載
- Interface は 変数を 型 と共に定義するもの
- TypeScript では 型 チェック による エラー チェック が有効
関連記事
本記事で使用した サンプルコード
script
<script lang="ts"> import { defineComponent } from 'vue' interface Person { name: string height: number } export default defineComponent({ data() { return { david: { name: 'David Beckham', height: 180.1 } as Person } } }) </script>
template
<template> {{ david.name.split(' ')}} {{ david.height.toFixed(2) }} </template>