簡體   English   中英

vue-class-component : 調用類方法時 TS2339

[英]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 實例

有時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.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM