プロジェクトの外から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
を書けば良いですか?一例・チュートリアル等ありますか?