[英]vue-class-component : TS2339 when calling class method
我正在使用 vue-cli-service 來構建我的 vuejs 應用程序。
構建成功,但在 webstorm IDE 中,我收到一些 TS2339 錯誤:
測試.vue:
<template>
<div>{{method()}}</div>
</template>
<script lang="ts">
import { Component, Vue } from 'vue-property-decorator';
@Component
export default class Test extends Vue {
public method(): string {
return 'hello';
}
}
</script>
測試規范:
import 'jest';
import {mount} from '@vue/test-utils';
import Test from '@/views/common/Test.vue';
describe('Test.vue', () => {
let wrapper: any;
beforeEach(() => {
wrapper = mount(Test);
});
test('test method call', () => {
const test = wrapper.find(Test).vm as Test;
expect(test.method()).toEqual('hello');
});
});
在 Test.spec.ts 中,我在編輯器和打字稿窗口中都收到此錯誤:
錯誤:(14, 21) TS2339:“Vue”類型上不存在屬性“方法”。
但是測試沒問題,所以test.method()
在運行時解析成功。
在您的通話之前添加這些。
// tslint:disable-next-line
// @ts-ignore
您還可以像這樣聯合現有的測試接口:
const test = wrapper.find(Test).vm as Test & {method()};
並不是說你應該在實踐中這樣做,但你的代碼會運行......
解決此問題的正確方法是augment
Vue's
定義,以便typescript
接受您的方法。 但這應該由 Vue 自動發生。 您是否包括shims-vue.d.ts
文件。 那就是打字稿魔術發生的地方?
https://v2.vuejs.org/v2/guide/typescript.html
話雖如此,我在使用 Vue 類語法時遇到了問題,不得不恢復到老式語法以避免打字稿抱怨:
<script lang="ts">
import Vue from 'vue';
export default Vue.extend({
methods: {
method(): string {
return 'hello';
}
})
</script>
shims 文件是 Vue 如何使用您的組件增強自身的方式。
shims-vue.d.ts
declare module '*.vue' {
import Vue from 'vue';
export default Vue;
有時Vue
包含在多個來源中,這會弄亂打字稿。
嘗試將此添加到您的tsconfig
文件中。
{
"paths": {
"@/*": [
"src/*"
],
"vue/*": [
"node_modules/vue/*"
]
}
我有時甚至不得不為此添加 webpack 別名(盡管這將是一個已發布的建築物,因此不能解決您的問題):
'vue$': path.resolve(__dirname, 'node_modules', 'vue/dist/vue.esm.js'),
根據史蒂文的回答,我了解到 shims-vue.d.ts 是使用組件作為打字稿類所必需的。 但問題是它們都被視為 Vue 實例。 查看此文件內容時,這一點很明顯:
declare module '*.vue' {
import Vue from 'vue';
export default Vue;
}
目前,我發現的唯一干凈的方法是聲明一個由我的組件實現的接口:
模型.ts:
export interface ITest {
method(): void;
}
測試.vue:
<template>
<div>{{method()}}</div>
</template>
<script lang="ts">
import { Component } from 'vue-property-decorator';
import Vue from 'vue';
import {ITest} from '@/views/test/model';
@Component
export default class Test extends Vue implements ITest {
public method(): string {
return 'hello';
}
}
</script>
測試規范:
import 'jest';
import {mount} from '@vue/test-utils';
import {ITest} from '@/views/test/model';
import Test from '@/views/test/Test.vue';
describe('Test.vue', () => {
let wrapper: any;
beforeEach(() => {
wrapper = mount(Test);
});
test('test method call', () => {
const test = wrapper.find(Test).vm as ITest;
expect(test.method()).toEqual('hello');
});
});
我注意到 Vue 文件能夠使用其他 Vue 文件作為它們聲明的類,這導致我嘗試將 Jest 文件也聲明為 Vue 組件。 令人驚訝的是,它起作用了——不需要額外的僅測試接口。
有兩個步驟。 首先,在你的package.json
中將.vue
后綴添加到 Jest 的測試配置中:
{
"jest": {
"testMatch": [
"**/__tests__/**/*.test.ts",
"**/__tests__/**/*.test.vue"
],
}
}
其次,將您的測試文件重命名為.test.vue
並將它們包裝在<script>
塊中:
<script lang="ts">
import 'jest';
import { shallowMount } from '@vue/test-utils';
// Tests here...
</script>
現在您可以使用wrapper.vm
作為實際聲明的組件類類型,並且 Vetur/Typescript 在 IDE 和編譯器輸出中都將完全滿意。
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.