vue-class-component : 调用 class 方法时的 TS2339
vue-class-component : TS2339 when calling class method
我正在使用 vue-cli-service 构建我的 vuejs 应用程序。
构建成功,但在 webstorm IDE 中,出现一些 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 中,我在编辑器和打字稿中都遇到了这个错误 window:
Error:(14, 21) TS2339: Property 'method' does not exist on type '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://vuejs.org/v2/guide/typescript.html
话虽如此,我在使用 Vue class 语法时遇到了问题,不得不恢复到旧式语法以避免打字稿抱怨:
<script lang="ts">
import Vue from 'vue';
export default Vue.extend({
methods: {
method(): string {
return 'hello';
}
})
</script>
垫片文件是 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;
}
目前,我发现的唯一干净的方法是声明一个由我的组件实现的接口:
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');
});
});
我注意到 Vue 文件能够使用其他 Vue 文件作为它们声明的 classes,这让我尝试将 Jest 文件也声明为 Vue 组件。令人惊讶的是,它起作用了——不需要额外的仅测试接口。
有两个步骤。首先,在 package.json
:
的 Jest 测试配置中添加 .vue
后缀
{
"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
作为实际声明的组件 class 类型,Vetur/Typescript 将完全满足 IDE 和编译器输出。
我正在使用 vue-cli-service 构建我的 vuejs 应用程序。
构建成功,但在 webstorm IDE 中,出现一些 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 中,我在编辑器和打字稿中都遇到了这个错误 window:
Error:(14, 21) TS2339: Property 'method' does not exist on type '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://vuejs.org/v2/guide/typescript.html
话虽如此,我在使用 Vue class 语法时遇到了问题,不得不恢复到旧式语法以避免打字稿抱怨:
<script lang="ts">
import Vue from 'vue';
export default Vue.extend({
methods: {
method(): string {
return 'hello';
}
})
</script>
垫片文件是 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;
}
目前,我发现的唯一干净的方法是声明一个由我的组件实现的接口:
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');
});
});
我注意到 Vue 文件能够使用其他 Vue 文件作为它们声明的 classes,这让我尝试将 Jest 文件也声明为 Vue 组件。令人惊讶的是,它起作用了——不需要额外的仅测试接口。
有两个步骤。首先,在 package.json
:
.vue
后缀
{
"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
作为实际声明的组件 class 类型,Vetur/Typescript 将完全满足 IDE 和编译器输出。