“Vue”类型上不存在属性“x”

Posted

技术标签:

【中文标题】“Vue”类型上不存在属性“x”【英文标题】:Property 'x' does not exist on type 'Vue' 【发布时间】:2020-12-18 03:23:48 【问题描述】:

我已经阅读了多个类似问题的答案,但大多数解决方案都是不恰当的解决方法。我希望得到关于为什么在this的所有实例上发生此错误的解释/解决方案的帮助:

类型“Vue”上不存在属性“x”

发生的组件(请注意,如果我删除计算属性showModal,则不再有任何错误)

<template>
  <v-row justify="center">
    <v-dialog id="edit-cattle" v-model="showModal" persistent scrollable max->
      <v-card>
        <v-card-title>
          <span class="headline">Edit Cattle</span>
        </v-card-title>
        <v-card-text>
          <v-form v-model="valid">
            <v-container>
              <v-select id="status" :items="statusOptions" label="Status" v-model="client.status"></v-select>
            </v-container>
          </v-form>
        </v-card-text>
      </v-card>
    </v-dialog>
  </v-row>
</template>

<script lang="ts">
import Vue from "vue";
import firebase,  firestore  from "firebase/app";
import constants from "../constants/constants";
import 
  Client,
  ClientLegalType,
  ClientStatus,
  Month,
  ClientBank,
  ClientBankAccountType
 from "../models/client.model";
import helpers from "../helpers/helpers";
import algoliasearch from "algoliasearch";

export default Vue.extend(
  name: "EditClient",
  props: 
    client: Object as () => Client,
    showModalValue: Boolean
  ,
  data() 
    return 
      postalSameAsPhysical: false,
      valid: false,
      loading: false,
      registrationDate: (this.client
        ?.registrationDate as firebase.firestore.Timestamp)
        ?.toDate()
        .toISOString()
        .substr(0, 10),
      legalTypeOptions: Object.keys(ClientLegalType).map(value => 
        return  text: helpers.camelToWords(value), value: value ;
      ),
      statusOptions: Object.keys(ClientStatus).map(value => 
        return  text: helpers.camelToWords(value), value: value ;
      ),
      monthOptions: Object.keys(Month).map(value => 
        return  text: helpers.camelToWords(value), value: value ;
      ),
      bankOptions: Object.keys(ClientBank).map(value => 
        return  text: helpers.camelToWords(value), value: value ;
      ),
      bankAccountTypeOptions: Object.keys(ClientBankAccountType).map(value => 
        return  text: helpers.camelToWords(value), value: value ;
      )
    ;
  ,
  methods: 
    passData() 
      const updatedClient: Client = 
        ...this.client //Property 'client' does not exist on type 'Vue'
      ;
      //Property 'registrationDate' does not exist on type 'Vue'
      if (this.registrationDate) 
        updatedClient.registrationDate = firebase.firestore.Timestamp.fromDate(
          new Date(this.registrationDate)
        );
      
      console.log("updatedClient: ", updatedClient);
      this.showModal = false; //Property 'showModal' does not exist on type 'Vue'.
      this.$emit("saveData", helpers.undefinedToNull(updatedClient));
    
  ,
  computed: 
    algoliaClient(): any 
      const client = algoliasearch(
        constants.ALGOLIA.APP_ID,
        constants.ALGOLIA.SEARCH_KEY
      );
      return client.initIndex(constants.ALGOLIA.INDEXES.CLIENTS);
    ,
    showModal: 
      get(): Boolean 
        return this.showModalValue //Property 'showModalValue' does not exist on type '(() => any) | ComputedOptions<any>'.;
      ,
      set(value) 
        this.$emit("updateShowModalValue", value); //Property '$emit' does not exist on type '(() => any) | ComputedOptions<any>'.
      
    
  ,
);
</script>

我的配置文件:

tsconfig.json


  "compilerOptions": 
    "target": "esnext",
    "module": "esnext",
    "strict": true,
    "jsx": "preserve",
    "importHelpers": true,
    "moduleResolution": "node",
    "skipLibCheck": true,
    "esModuleInterop": true,
    "allowSyntheticDefaultImports": true,
    "noImplicitThis": false,
    "sourceMap": true,
    "baseUrl": ".",
    "types": ["webpack-env", "vuetify"],
    "paths": 
      "@/*": ["src/*"]
    ,
    "lib": ["esnext", "dom", "dom.iterable", "scripthost"]
  ,
  "include": ["src/**/*.ts", "src/**/*.tsx", "src/**/*.vue", "tests/**/*.ts", "tests/**/*.tsx"],
  "exclude": ["node_modules"]

package.json


  "name": "xxx",
  "version": "0.1.0",
  "private": true,
  "scripts": 
    "serve": "vue-cli-service serve",
    "build": "vue-cli-service build",
    "lint": "vue-cli-service lint"
  ,
  "dependencies": 
    "algoliasearch": "^4.4.0",
    "core-js": "^3.6.5",
    "eslint-config-prettier": "^6.11.0",
    "firebase": "^7.19.1",
    "moment": "^2.27.0",
    "register-service-worker": "^1.7.1",
    "vue": "^2.6.11",
    "vue-router": "^3.2.0",
    "vuetify": "^2.2.11",
    "vuex": "^3.4.0"
  ,
  "devDependencies": 
    "@typescript-eslint/eslint-plugin": "^2.33.0",
    "@typescript-eslint/parser": "^2.33.0",
    "@vue/cli-plugin-babel": "~4.5.0",
    "@vue/cli-plugin-eslint": "~4.5.0",
    "@vue/cli-plugin-pwa": "~4.5.0",
    "@vue/cli-plugin-router": "~4.5.0",
    "@vue/cli-plugin-typescript": "~4.5.0",
    "@vue/cli-plugin-vuex": "~4.5.0",
    "@vue/cli-service": "~4.5.0",
    "@vue/eslint-config-prettier": "^6.0.0",
    "@vue/eslint-config-typescript": "^5.0.2",
    "eslint": "^6.7.2",
    "eslint-plugin-prettier": "^3.1.3",
    "eslint-plugin-vue": "^6.2.2",
    "prettier": "^1.19.1",
    "sass": "^1.19.0",
    "sass-loader": "^8.0.0",
    "typescript": "~3.9.3",
    "vue-cli-plugin-vuetify": "~2.0.7",
    "vue-template-compiler": "^2.6.11",
    "vuetify-loader": "^1.3.0"
  

eslintrc.js

module.exports = 
  root: true,
  env: 
    node: true,
  ,
  extends: [
    'plugin:vue/essential',
    'eslint:recommended',
    '@vue/typescript/recommended',
    '@vue/prettier',
    '@vue/prettier/@typescript-eslint',
  ],
  parserOptions: 
    ecmaVersion: 2020,
  ,
  rules: 
    'no-console': process.env.NODE_ENV === 'production' ? 'warn' : 'off',
    'no-debugger': process.env.NODE_ENV === 'production' ? 'warn' : 'off',
  ,
;

垫片-tsx.d.ts

import Vue,  VNode  from "vue";

declare global 
  namespace JSX 
    // tslint:disable no-empty-interface
    interface Element extends VNode 
    // tslint:disable no-empty-interface
    interface ElementClass extends Vue 
    interface IntrinsicElements 
      [elem: string]: any;
    
  

shims-vue.d.ts

declare module "*.vue" 
  import Vue from "vue";
  export default Vue;

【问题讨论】:

当我在计算属性 showModal: set(value: boolean) 中键入 set 方法时,错误已修复。仍然希望解释为什么会发生这种情况,因为这是一个误导性错误。 【参考方案1】:

最好为要进入组件的 props 键入和设置默认值,特别是在 TypeScript 下。

这里的问题是因为计算属性的类型定义,它期望返回一个 false,但 showModalValue 属性没有默认值。所以它最初是 undefined,纯 javascript undefined 是错误的,但不是在 TypeScript 中。

将prop默认设置为false,错误应该消失了。

【讨论】:

谢谢。已经尝试给'showModalValue'一个默认值false,仍然相同的错误。但是,当我将showModal的set方法从'set(value)'更改为'set(value:boolean)'时,所有错误都消失了。不确定是什么 Typescript 机制导致了这种奇怪的行为。

以上是关于“Vue”类型上不存在属性“x”的主要内容,如果未能解决你的问题,请参考以下文章

全局属性的“功能”类型上不存在 Vue3 属性“x”

使用 this.$parent.somePropOrMethod 和 this.$root.somePropOrMethod 时,类型“Vue”上不存在属性 X

“Vue”类型上不存在属性“$keycloak”

Vue js 3 - 类型“CreateComponentPublicInstance<、、、、 上不存在属性“项目”,

类型 ' $route(currentRoute: any): void; 上不存在属性' 在 Ionic Vue 中

Vue.js 3 属性“$store”在“CreateComponentPublicInstance”类型上不存在