Vue.jsとTypeScriptで起こるProperty 'xxxx' does not exist on type 〇〇 のエラーが分かり辛い

scienceportal.jst.go.jp

 人類の暮らしを支え、歴史とともに活用の幅が広がってきたガラス。その魅力を多くの人に知ってもらおうと、文部科学省が学習資料のポスター「ガラス 人類と歩んできた万能材料」を作成した。今年が国連「国際ガラス年」であることから、今月18~24日の科学技術週間を前に公開したもの。国民が科学技術に触れる機会を、と公開を続ける「一家に1枚」シリーズの18枚目となった。

ガラスの歴史と魅力に迫る 「一家に1枚」ポスターに新顔 | Science Portal - 科学技術の最新情報サイト「サイエンスポータル」

⇧ 何と言いますか、「一家に1枚」シリーズの18枚目も何も、「一家に1枚」シリーズというものの存在をたった今知る今日この頃。

「ガラス 人類と歩んできた万能材料」には、

pc.watch.impress.co.jp

 日立製作所では、2009年より耐熱性や耐水性に優れる石英ガラスにデータを記録する技術を開発しており、2012年には4層記録でCD並の記録密度、2013年には26層でDVD並の記録密度を実現してきた。1,000℃で2時間加熱しても保存データの劣化がないことを実証済みで、3億年を超えるデータ保存に耐えうることを示している。

日立、3億年保存できる石英ガラスへの100層データ記録に成功 ~「しんえん2」に乗って宇宙へ - PC Watch

pc.watch.impress.co.jp

 石英ガラス内に保存することで、従来の磁性体などへの保存と異なり、熱湯で煮る、オーブンで焼く、電子レンジで加熱する、浸水、消磁などを行なってもデータを損失することがないため、歴史的資料などの保管手段としての活用が期待されている。実際に500℃のオーブンに入れ電子レンジで加熱、沸騰、スチールウールで磨くなどしてもデータの損失はなかったという。

Microsoft、煮ても焼いても喪失しない石英ガラスデータ記録技術 ~映画「スーパーマン」の記録に成功 - PC Watch

⇧ このあたりの情報についても解説してくれてるのかしら?

犯人はVS CodeVisual Studio Code)とVeturでした...

かなり泥沼にハマったので、備忘録。

自分の場合は、Vue.jsのコンポーネントの中で、

this.$route.query.params    

という記載をしてたのですが、

『property '$route' does not exist on type UserFormEdit』ってエラーが出て、Vue Routerとかもnpmのライブラリはインストールしてるし、importもして読み込んでるんだけど、なんか、そもそも、thisがVue Routerのオブジェクトとして認識されてないってことなのか、何でや!ってなって、いろいろググってみるも、

stackoverflow.com

qiita.com

teratail.com

決定打に欠ける情報で、時間だけが経過していくという...

で、もう一度、エラー見てみると、Vetur(2339)って表示されていて、

VS CodeVisual Studio Code)」のVue.js向けの拡張機能で、「Vetur」ってものがあるんですが、まさかの「Vetur」さんと「VS CodeVisual Studio Code)」が悪さをしてくれてました...

GitHubに上がってるissueなんかを見ると、

github.com

github.com

⇧ 何か、「Vetur」の問題なんじゃないか説が出ていて、

zukucode.com

jpdebug.com

過去に動いていたのに環境を変更したら、

Vetur(2339)
Vetur(2306)
Vetur(2307) …etc

が発生するようになった。※インテリセンスが効かない

VSCode + Vetur で Typescript の Paths が解決できない。 - JPDEBUG.COM

VSCodeのVeturはワークスペースのルートディレクトリから順に解決するため、作業ディレクトリ直下にtsconfig.jsonがあるようにすると手っ取り早いです。

VSCode + Vetur で Typescript の Paths が解決できない。 - JPDEBUG.COM

⇧上記サイト様によりますと、「VS CodeVisual Studio Code)」と「Vetur」の影響が怪しいですと。

自分の場合は、「Vetur」の言及してるプロジェクトルートが「VS CodeVisual Studio Code)」のワークスペース基準となっていないところが原因でした。

公式のドキュメントを見ると、

vuejs.github.io

How to find vetur.config.js

  • Start from the root and work your way up until the file is found.
  • The root is set process.cwd() value in VTI and you can set file path in CLI params.

PS. Each root can have its own vetur.config.js in VSCode Multi root feature.

https://vuejs.github.io/vetur/reference/#how-to-use

⇧ 確かに、ルートから探していくとなってますと。

rootがどこかについては、VTIの中で定義されてるらしく、VTIが何なのかについては、

Noun

  • Vetur: a VSCode extension for Vue support.
  • VTI: a CLI for Vue file type-check, diagnostics or some feature.
  • VLS: vue language server, The core of everything. It is base on language server protocol

https://vuejs.github.io/vetur/reference/#noun

⇧ 上記に記載があり、Vue fileに対しての型チェックを担うCLIということらしい。

github.com

Vetur Terminal Interface

VTI is a CLI that exposes some of Vetur's language features:

https://github.com/vuejs/vetur/tree/master/vti

⇧ Veturの一部の機能って説明が引っかかりますが...

VTIの実体はと言うと、

github.com

#!/usr/bin/env node
require('../dist/cli.js')    

⇧ となっていて、distフォルダにcli.jsってファイルが配置されてるってことみたい。

そもそも、「VS CodeVisual Studio Code)」の拡張機能「Vetur」をインストールした場合に、「VTI」も一緒にインストールされてるって考えて良いのか、「Vetur」がどこに配置されるかについての記載が見当たらず、確認がし辛いですな...

致し方ないから、WindowsのCドライブ直下で検索をかけてみます、時間かかりますんで暫く放置。

で、検索が完了。

veturで検索してヒットしたファイルが該当ファイルなのか?

自分の環境では、『C:\Users\Toshinobu\.vscode\extensions\octref.vetur-0.35.0\server\node_modules\eslint\lib』って場所にありました。

というか、フォルダ名にeslintって入ってるのですが、Veturって内部的には、eslintを使ってるってことなんですかね?謎が多過ぎる...

で、cli.jsを確認してみたところ、

⇧ process.cwd()が、1カ所記載されてますと。

う~ん、VTIが、「C:\Users\ユーザー名\.vscode\extensions\octref.vetur-x.xx.x\server\node_modules\eslint\lib\cli.js」というファイルで良いのかが分からないので、何とも言えませんな...教えて偉い人。

話が脱線しましたが、「Vetur」の言及してるプロジェクトルートが、

vuejs.github.io

If you use a monorepo, VTI or package.json and tsconfig.json/jsconfig.json does not exist at project root, you can use vetur.config.js for advanced settings.

https://vuejs.github.io/vetur/guide/setup.html#typescript

Please add vetur.config.js at project root or monorepo project root.

https://vuejs.github.io/vetur/guide/setup.html#typescript

⇧ どうも、「VS CodeVisual Studio Code)」で「.vscode」ってフォルダを作ってる場合は、「.vscode」のフォルダがある場所がプロジェクトルートと認識されてしまうらしいので、vuter.config.jsのファイルの配置場所を変えれば良いらしい。

自分の場合ですと、

⇧ 上記のフォルダがプロジェクトルートということになるらしい。「my-project-vue」のほうがVue CLIで作成したプロジェクトなんで、てっきり、「my-project-vue」がプロジェクトルートになると思ってたんですけど、然に非ず。

「Vetur」ってVue.js用の拡張機能なんで、Vue.jsのプロジェクトのフォルダがプロジェクトルートになるって思い込んでしまっていたわけです...

というか参考サイト様にあったように、環境を変えたら動いてたのが動かなくなったってことは何か、「Vetur」の仕様か「VS CodeVisual Studio Code)」の仕様か分からないですが、変わったってことなんですかね?

結構、GitHubのissueで議論が上がってるようですし...

話が脱線しましたが、「my-project-vue」に配置されてる「vetur.config.js」を

「.vscode」フォルダのあるフォルダに移動してみました。

で、VS CodeVisual Studio Code)を再起動。

⇧ $routeがVue Routerの型として認識されるようになりました。

ちなみに、「vetur.config.js」の中身は、

■C:\Users\Toshinobu\Desktop\soft_work\vue_work\vue-router-work\vetur.config.js

// vetur.config.js
/** @type {import('vls').VeturConfig} */
module.exports = {
  // **optional** default: `{}`
  // override vscode settings
  // Notice: It only affects the settings used by Vetur.
  settings: {
    "vetur.useWorkspaceDependencies": false,
    "vetur.experimental.templateInterpolationService": true,
  },
  // **optional** default: `[{ root: './' }]`
  // support monorepos
  projects: [
    {
      // **required**
      // Where is your project?
      // It is relative to `vetur.config.js`.
      root: "./my-project-vue", // ←ここをvueプロジェクトのフォルダに合わせる
      // **optional** default: `'package.json'`
      // Where is `package.json` in the project?
      // We use it to determine the version of vue.
      // It is relative to root property.
      package: "./package.json",
      // **optional**
      // Where is TypeScript config file in the project?
      // It is relative to root property.
      tsconfig: "./tsconfig.json",
      // **optional** default: `'./.vscode/vetur/snippets'`
      // Where is vetur custom snippets folders?
      snippetFolder: "./.vscode/vetur/snippets",
      // **optional** default: `[]`
      // Register globally Vue component glob.
      // If you set it, you can get completion by that components.
      // It is relative to root property.
      // Notice: It won't actually do it. You need to use `require.context` or `Vue.component`
      globalComponents: ["./src/components/**/*.vue"],
    },
  ],
};
    

⇧ というような感じにしてます。

推奨されてる拡張機能で、こんな混乱させられるとは...

というか、「VS CodeVisual Studio Code)」の設定周りが安定しなくて辛い...

かなりニッチな情報なので、誰の役にも立たないかもしれないけど、同じ様に躓いておられる方の参考になればと思い、備忘録として記載します。

自分は何だかんだで、ほぼ1日潰れたので...

ちなみに、Veturが適切に機能すると、

jpdebug.com

vscodeを使っていて、Vueプロジェクトでいつからか急にtemplate内で型への警告が出るようになりました。

Typescriptを導入しているプロジェクトではなく、型への警告を出されてもちょっと困るなあと思っていました。

Typescriptを使ってないプロジェクトでVeturのtemplate内での型推論の警告(Vetur2339)が出てしまう問題への対処法 - JPDEBUG.COM

どうやら、原因はVueを書くなら誰もが入れるであろうvscode拡張機能のVeturのtemplate内での型推論機能が働いているようでした。

Typescriptを使ってないプロジェクトでVeturのtemplate内での型推論の警告(Vetur2339)が出てしまう問題への対処法 - JPDEBUG.COM

⇧ 上記サイト様にありますように、TypeScript使ってないプロジェクトでも型推論されてしまうようです...

まとめると、Vue.jsとTypeScriptでVeturを使ってるケースで起こる『Property 'xxxx' does not exist on type 〇〇 』のエラーについては、

  • Property 'xxxx' does not exist on type 〇〇
    • Veturが適切に機能していない
    • Veturが型推論を解決できない

のどちらかで、起きるようです。

あと、『Property 'xxxx' does not exist on type 〇〇 』に関して、

  • Vetur(2339)
  • TS2339

で起こる場合の違いを知りたいのですが、

github.com

⇧ 上記で『does not exist on type』などで検索してもヒットせず、

github.com

⇧ 上記でヒットしたことから、メッセージは「TypeScript」側で作ってるっぽい気がしますかね。

「TypeScript」が直に型の検証してるか、「Vetur」が型の検証してるかの違いってことなんだろうか?

どちらにしろ、最終的には、「TypeScript」で用意されてるメッセージが表示されるようではありますが、ブラックボックス化しててよく分かりません...

結局、本質的なところは何も分からないという徒労感...

そして、「VS CodeVisual Studio Code)」を使う場合に、拡張機能と設定周りの混沌さ、どうにかして欲しい...

今回はこのへんで。