プロジェクトの外からTypeScriptで実装されたVueコンポーネントをインポートする時にエラーTS2345 を予防する
プロジェクト・ディレクトリの外からvue-property-decoratorで実装されたVueコンポーネントをインポートしてみて、TypeScriptコンパイルの時に下記のエラーが出ました:
TS2345: Argument of type '{ template: string; components: { SimpleCheckbox: typeof SimpleCheckbox; }; }'
is not assignable to parameter of type 'VueClass<Vue>'.
Object literal may only specify known properties, and 'template' does not exist in type
'VueClass<Vue>'.
WebStromは此のエラーに就いて警告を出しません、エラーが出ているのはWebpackを実行する時だけです(TypeScriptのローダーはts-loaderです)。
エラーが起きている所は:
import { Vue, Component, Prop } from 'vue-property-decorator';
import template from './SkipProjectInitializationStepPanel.pug';
import SimpleCheckbox from './../../../../ui-kit-libary-in-development/UiComponents/Checkboxes/MaterialDesign/SimpleCheckbox.vue';
// ここです!
@Component({ template, components: { SimpleCheckbox } })
export default class SkipProjectInitializationStepPanel extends Vue {
@Prop({ type: String, required: true }) private readonly text!: string;
}
ui-kit-libary-in-developmentという名前からわかる通り、これは開発中のライブラリで未だnpm依存性ではないので、node_modulesの中にはありません。
これはTypeScriptだけのエラーで、ts-loaderにより起きるものの、Webpackでコンパイル・ビルドされたアプリのJavaScriptは正常に動いています(ブラウザーのコンソールにエラーは一切ありません)。
下記の対策を取れば、エラーが無くなります:
SimpleCheckbox.vueをSkipProjectInitializationStepPanel.tsと同じディレクトリに移動しimport SimpleCheckbox from './SimpleCheckbox.vue';の様にインポートします。@Component({ template, components: { SimpleCheckbox } })からSimpleCheckboxを取り除き、@Component({ template, components: {} })だけ残します。 (勿論、SimpleCheckboxはレンダリングされなくなりますが、実験の為に確認するべきの事でした)ui-kit-libary-in-developmentを主要プロジェクトのnode_modulesに移動した上で、ui-kit-libary-in-developmentからこれのnode_modulesを取り除きます(取り除かなければ、エラーが変わらなく、無くなりません。従って、npm linkは問題解決に成りません)
残念ながら、このエラーの再現は出来ませんでした。どういう訳か、下記のコードではエラーが再現しません:
MainProject/src/Application.vue
<template lang="pug">
PageOne
</template>
<script lang="ts">
import { Vue, Component } from 'vue-property-decorator';
import PageOne from './PageComponents/PageOne'
@Component({ components: { PageOne }})
export default class Application extends Vue {
private created(): void {
console.log('Done.');
}
}
</script>
MainProject/src/PageComponents/PageOne.ts
import { Vue, Component, Prop } from 'vue-property-decorator';
import template from './PageOne.pug';
import Button from './../../../UiKitLibraryStillInDevelopment/UiComponents/Buttons/Button.vue';
@Component({ template, components: { Button } })
export default class SkipProjectInitializationStepPanel extends Vue {}
MainProject/src/PageComponents/PageOne.pug
.RootElement
Button(:text="'Click me'")
ui-kit-libary-in-development/UiComponents/Buttons/Button.vue
<template lang="pug">
button {{ text }}
</template>
<script lang="ts">
import { Vue, Component, Prop } from 'vue-property-decorator';
@Component
export default class SimpleCheckbox extends Vue {
@Prop({ type: String, required: true }) private readonly text!: string;
private created(): void {
console.log('OK!');
console.log(this.$props);
}
}
</script>
エラーの解決の助言の中に見つけたのはGitHubのissueからのこのコメントだけです:
私が知っている限り、正常な動きの為に外部のコンポネントに
.d.tsが必要。
Side components should add .d.ts for it to work AFAIK.
でも、このコメントによって、私の中に新たな質問が生まれました:
.d.tsを作らなければならないのは、どこですか?主要なプロジェクトですか、依存性ですか? 主要なプロジェクトだとしたら、何故vuetifyの様なライブラリからコンポーネントが無事にインポートされますか? あちらで.d.tsがありますから!- どうやって
vue-property-decoratorを使う場合の.d.tsを書けば良いですか?一例・チュートリアル等ありますか?