vue-class-component: TS2339 при вызове метода класса - PullRequest
0 голосов
/ 05 июня 2019

Я использую vue-cli-service для создания своего приложения vuejs.

Сборка прошла успешно, но в IDE webstorm я получаю некоторые ошибки TS2339:

Test.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>

Test.spec.ts:

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: Свойство 'method' не существует для типа 'Vue'.

Но тест в порядке, поэтому test.method() успешно разрешен во время выполнения.

Ответы [ 2 ]

0 голосов
/ 05 июня 2019

Основываясь на ответе Стивена, я понял, что shims-vue.d.ts необходим для использования компонента в качестве классов машинописи.Но проблема в том, что все они рассматриваются как экземпляры Vue.Это очевидно при просмотре содержимого этого файла:

declare module '*.vue' {
  import Vue from 'vue';
  export default Vue;
}

На данный момент единственный чистый способ, который я нашел, - это объявить интерфейс, реализованный моим компонентом:

model.ts:

export interface ITest {
    method(): void;
}

Test.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>

Test.spec.ts:

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');
    });
});
0 голосов
/ 05 июня 2019

Добавьте их до звонка.

// tslint:disable-next-line 
// @ts-ignore 

Вы также можете объединить существующий интерфейс Test следующим образом:

const test = wrapper.find(Test).vm as Test & {method()};

Не сказать, что вы должны делать это на практике, но ваш код будет работать ...

правильный способ исправить это - augment Vue's определение, поэтому typescript примет ваш метод. Но это должно происходить автоматически Vue. Включаете ли вы файл shims-vue.d.ts. Вот где происходит волшебство машинописи?

https://vuejs.org/v2/guide/typescript.html

С учетом вышесказанного у меня возникли проблемы с использованием синтаксиса класса Vue, и мне пришлось вернуться к синтаксису oldschool, чтобы избежать жалоб на машинопись:

<script lang="ts">
    import Vue from 'vue';

    export default Vue.extend({
        methods: {
          method(): string {
            return 'hello';
        }
    })
</script>

Файл shims - это то, как Vue дополняет себя вашими компонентами.

проставки-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'),
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...