【问题标题】:Property 'XXX' does not exist on type 'CombinedVueInstance<Vue, {}, {}, {}, Readonly<Record<never, any>>>'类型“CombinedVueInstance<Vue, {}, {}, {}, Readonly<Record<never, any>>> 上不存在属性“XXX”
【发布时间】:2019-09-23 22:03:09
【问题描述】:

我使用 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 typescript vue.js vuejs2 vue-component


    【解决方案1】:

    如 Vue 文档的 Typescript Support 部分所述:

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

    在您的情况下,您应该将profilePath: function () { 更改为profilePath: function (): string {

    如果您有一个返回值但没有: VNode 注释的 render() 方法,您可能会遇到同样的错误。

    【讨论】:

      【解决方案2】:

      这似乎是由于使用this.$store 计算profilePath 的返回值,并结合其声明中未指定的返回类型造成的。

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

      profilePath: function(): string {
      

      已通过 npm run servenpm run build 验证,在 macOS Mojave 上使用 Vue CLI 3.7.0

      GitHub demo

      【讨论】:

      • 这对我有用,我必须指定计算属性的返回类型。
      【解决方案3】:

      2021 年 12 月更新:

      vetur.experimental.templateInterpolationService 更改为 false

      对于VSCode,您可以使用搜索图标?找到它:

      那么,默认是true

      然后,将其更改为 false

      终于,错误解决了。

      【讨论】:

        【解决方案4】:

        试试这个:

        (this as any).open
        

        这也适用于注入的属性:

        (this as any).injectedProp
        

        还有$refs

        (this as any).$refs.myElement
        

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

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

        【讨论】:

          【解决方案5】:

          我得到以下错误: Property 'doThisInput' does not exist on type 'CombinedVueInstance&lt;Vue, unknown, unknown, unknown, Readonly&lt;Record&lt;never, any&gt;&gt;&gt;'.

          还有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>
          
          

          【讨论】:

            【解决方案6】:

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

            所以而不是:

            myComputedProperty() {
              return this.foo;
            },
            

            我不得不这样做

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

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

            【讨论】:

            • 这对我来说是正确的答案
            【解决方案7】:

            我在使用 VS Code 编辑器时遇到了这个错误。

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

            请在你的 VS 编辑器上找到这个文件,然后像下面这样设置更改

            .vscode/settings.json

            "vetur.experimental.templateInterpolationService": false
            

            【讨论】:

              【解决方案8】:

              我在使用 typescript 时已经看到这个问题好几次了。我不确定这是否是 vue-tsc 或其他问题,但这是解决 linter 警告/错误的解决方案。 (它可能发生在 Vue 之外,但这是我所看到的。我相信任何其他 lib/框架的解决方案都是相同的。)

              通常问题看起来像这样......

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

              【讨论】:

                【解决方案9】:

                此处描述了相同的问题 https://www.gitmemory.com/issue/vuejs/vue/9873/485481541

                作为 TS 3.4.x 的问题,3.9.6 现在对我来说效果很好

                【讨论】:

                  【解决方案10】:

                  临时解决方案是降级到以前的版本,直到解决此问题。将 vuter 版本降级为 0.26.0 并且可以正常工作。

                  【讨论】:

                    【解决方案11】:

                    你需要以正确的方式使用function来保留this的引用。

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

                    【讨论】:

                    • 这似乎没有改变任何东西,仍然得到相同的错误。
                    猜你喜欢
                    • 2022-01-23
                    • 2023-04-03
                    • 2022-01-03
                    • 2021-12-28
                    • 2021-12-19
                    • 1970-01-01
                    • 2022-10-16
                    • 2020-11-07
                    • 2020-01-24
                    相关资源
                    最近更新 更多