我使用 TypeScript 创建了一个 vue 组件,并且在
data()
和 methods()
中收到此错误:
Property 'xxx' does not exist on type 'CombinedVueInstance<Vue, {},
{}, {}, Readonly<Record<never, any>>>'.
例如:
33:18 Property 'open' does not exist on type 'CombinedVueInstance<Vue, {}, {}, {}, Readonly<Record<never, any>>>'.
31 | methods: {
32 | toggle: function () {
> 33 | this.open = !this.open
| ^
34 | if (this.open) {
35 | // Add click listener to whole page to close dropdown
36 | document.addEventListener('click', this.close)
每当使用
this.close()
时也会显示此错误。
这是组件:
<script lang='ts'>
import Vue from 'vue';
import axios from 'axios'
export default Vue.extend({
data: function () {
return {
open: false
}
},
computed: {
profilePath: function () {
return "/user/" + this.$store.state.profile.profile.user.id
}
},
methods: {
toggle: function () {
this.open = !this.open
if (this.open) {
// Add click listener to whole page to close dropdown
document.addEventListener('click', this.close)
}
},
close: function () {
this.open = false;
document.removeEventListener('click', this.close)
}
}
})
</script>
什么原因导致此错误?它似乎仍然是在开发过程中出现的错误,但当我部署到生产环境时,它们会导致问题。
如 Vue 文档的 Typescript 支持 部分所述:
由于 Vue 声明文件的循环性质,TypeScript 可能难以推断某些方法的类型。因此,您可能需要在 render 和计算等方法上注释返回类型。
就您而言,您应该将
profilePath: function () {
更改为 profilePath: function (): string {
如果您有一个返回值的 render() 方法,但没有
: VNode
注释,您可能会遇到相同的错误。
对我来说,解决方案是显式定义所有计算属性、方法等的返回值。
所以代替:
myComputedProperty() {
return this.foo;
},
我必须这么做
myComputedProperty(): boolean {
return this.foo;
},
即使我期望,根据类型推断,这应该是不必要的
我收到以下错误:
Property 'doThisInput' does not exist on type 'CombinedVueInstance<Vue, unknown, unknown, unknown, Readonly<Record<never, any>>>'.
而且
doThisClick
也给出了同样的错误。
解决方案: 我已将
declaration
添加到组件中。
<script lang="ts">
import Vue from 'vue';
// Add below code sample to your component
declare module 'vue/types/vue' {
interface Vue {
fields: Field[];
doThisClick: () => void;
doThisInput: () => void;
}
}
export default Vue.extend({
name: 'form-builder',
data() {
return {
fields: [
{
name: 'name',
events: { click: this.doThisClick, input: this.doThisInput },
},
],
};
},
methods: {
doThisClick(field: Field): void {
console.log('click', field, event);
},
doThisInput(field: Field): void {
console.log('Input', field, event);
},
},
});
</script>
这似乎是由于使用
this.$store
来计算 profilePath
的返回值,再加上其声明中未指定的返回类型而导致的。
一种解决方法是将返回类型指定为
string
:
profilePath: function(): string {
已通过
npm run serve
和 npm run build
进行验证,在 macOS Mojave 上使用 Vue CLI 3.7.0
试试这个:
(this as any).open
这也适用于注入的属性:
(this as any).injectedProp
和$refs:
(this as any).$refs.myElement
编译器可以显示警告,但可以工作
重要:这是一个临时解决方案,使用类组件更优雅
我在使用 VS Code 编辑器时遇到此错误。
我在 vs code 上安装了 Vetur 插件,Vetur 将 vue 文件处理为 typescript 文件,所以我将其修复为编辑 settings.json 文件
请在 VS 编辑器中找到此文件,然后按如下所示进行更改
.vscode/settings.json
"vetur.experimental.templateInterpolationService": false
在使用打字稿时,我已经看到这个问题多次出现。我不确定这是否是
vue-tsc
或其他问题,但这是解决 linter 警告/错误的解决方案。 (它可能发生在 Vue 之外,但这就是我看到的地方。我确信该解决方案对于任何其他库/框架都是相同的。)
通常问题看起来像这样......
TS2339: Property 'title' does not exist on type 'CombinedVueInstance<Vue, unknown, unknown, unknown, Readonly<Record<never, any>>>'.
解决方案是定义一些类型,以便 Vue 知道组件中尝试定义什么。
interface IData {
title: string;
}
interface IProps {
}
interface IComputed {
}
interface IMethods {
}
export default Vue.extend<IData, IMethods, IComputed, IProps>({
data() {
title: "Some title"
}
});
另请注意,传递类型参数的顺序很重要。顺序遵循 DMCP(数据、方法、计算、道具)。
临时解决方案是降级到之前的版本,直到问题解决为止。将 vuter 版本降级为
0.26.0
并且可以正常工作。
此处描述了相同的问题:https://github.com/vuejs/vue/issues/9873
https://www.gitmemory.com/issue/vuejs/vue/9873/485481541
由于 TS 3.4.x 存在问题,3.9.6 现在对我来说效果很好
您需要以正确的方式使用
function
以保留此引用。
methods: {
toggle() {
this.open = !this.open
if (this.open) {
// Add click listener to whole page to close dropdown
document.addEventListener('click', this.close)
}
},
close() {
this.open = false;
document.removeEventListener('click', this.close)
}
}
我在常规 vs 代码设置中插入了这些 vetur 设置并且它起作用了
"vetur.useWorkspaceDependencies": true,
"vetur.validation.templateProps": true,
"[vue]": {
"editor.defaultFormatter": "octref.vetur"
},
"vetur.format.options.tabSize": 4,
"vetur.format.defaultFormatter.html": "prettier",
"vetur.format.defaultFormatter.css": "prettier",
"vetur.format.defaultFormatter.js": "vscode-typescript",
"vetur.format.defaultFormatter.ts": "vscode-typescript",
"vetur.format.defaultFormatterOptions": {
"js-beautify-html": {
"wrap_attributes": "force-expand-multiline"
},
"prettyhtml": {
"printWidth": 100,
"singleQuote": false,
"wrapAttributes": false,
"sortAttributes": false
}
},