“CombinedVueInstance<Vue, {}, {}, {}, Readonly<Record<never, any>>>”类型上不存在属性“XXX”

问题描述 投票:0回答:12

我使用 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>

什么原因导致此错误?它似乎仍然是在开发过程中出现的错误,但当我部署到生产环境时,它们会导致问题。

javascript node.js typescript vue.js vue-component
12个回答
63
投票

如 Vue 文档的 Typescript 支持 部分所述:

由于 Vue 声明文件的循环性质,TypeScript 可能难以推断某些方法的类型。因此,您可能需要在 render 和计算等方法上注释返回类型。

就您而言,您应该将

profilePath: function () {
更改为
profilePath: function (): string {

如果您有一个返回值的 render() 方法,但没有

: VNode
注释,您可能会遇到相同的错误。


22
投票

对我来说,解决方案是显式定义所有计算属性、方法等的返回值。

所以代替:

myComputedProperty() {
  return this.foo;
},

我必须这么做

myComputedProperty(): boolean {
  return this.foo;
},

即使我期望,根据类型推断,这应该是不必要的


14
投票

我收到以下错误:

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>


11
投票

这似乎是由于使用

this.$store
来计算
profilePath
的返回值,再加上其声明中未指定的返回类型而导致的。

一种解决方法是将返回类型指定为

string
:

profilePath: function(): string {

已通过

npm run serve
npm run build
进行验证,在 macOS Mojave 上使用 Vue CLI 3.7.0

GitHub 演示


11
投票

试试这个:

(this as any).open

这也适用于注入的属性:

(this as any).injectedProp

$refs

(this as any).$refs.myElement

编译器可以显示警告,但可以工作

重要:这是一个临时解决方案,使用类组件更优雅


9
投票

2022 年 1 月更新:

vetur.experimental.templateInterpolationService
更改为
false

对于

VSCode
,您可以通过搜索图标找到它🔎:

然后默认是

true

然后,将其更改为

false

终于解决了错误。


6
投票

我在使用 VS Code 编辑器时遇到此错误。

我在 vs code 上安装了 Vetur 插件,Vetur 将 vue 文件处理为 typescript 文件,所以我将其修复为编辑 settings.json 文件

请在 VS 编辑器中找到此文件,然后按如下所示进行更改

.vscode/settings.json

"vetur.experimental.templateInterpolationService": false

6
投票

在使用打字稿时,我已经看到这个问题多次出现。我不确定这是否是

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(数据、方法、计算、道具)。


1
投票

临时解决方案是降级到之前的版本,直到问题解决为止。将 vuter 版本降级为

0.26.0
并且可以正常工作。


1
投票

此处描述了相同的问题:https://github.com/vuejs/vue/issues/9873

https://www.gitmemory.com/issue/vuejs/vue/9873/485481541

由于 TS 3.4.x 存在问题,3.9.6 现在对我来说效果很好


0
投票

您需要以正确的方式使用

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)
            }
        }

0
投票

我在常规 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

    }

},
© www.soinside.com 2019 - 2024. All rights reserved.