typescript - Egenskapen 'x' eksisterer ikke på typen 'Vue'
Jeg har lest flere svar på lignende spørsmål, men de fleste løsningene er en uhensiktsmessig midlertidig løsning. Jeg vil gjerne ha hjelp med en forklaring/løsning på hvorfor denne feilen oppstår på alle forekomster av this:
Egenskapen 'x' finnes ikke på typen 'Vue'
Komponent der det oppstår (merk at hvis jeg fjerner den beregnede egenskapen showModal, er det ikke lenger noen feil):
<template>
<v-row justify="center">
<v-dialog id="edit-cattle" v-model="showModal" persistent scrollable max-width="600px">
<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>
Mine konfigurasjonsfiler:
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',
},
};
shims-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;
}
Svar #1
Det er en god praksis å skrive og sette standardverdier for propsene du mottar i komponenten, spesielt under TypeScript.
Problemet her er på grunn av din typedefinisjon av den beregnede egenskapen, den forventer å returnere false, men showModalValue-propen har ikke en standardverdi. Så den er i utgangspunktet undefined, med vanlig JavaScript er undefined falsy, men ikke i TypeScript.
Sett egenskapen som standard til false og feilen bør være borte.
Svar #2
Jeg hadde det samme problemet, bare på en av flere komponenter selv om de er skrevet på samme måte... merkelig.
Jeg fikset endelig det ved å skrive hele options-objektet som ble sendt til Vue.extend med ThisTypedComponentOptionsWithRecordProps<Vue, DefaultData<any>, DefaultMethods<any>, DefaultComputed, DefaultProps>.
import Vue from "vue";
import {
DefaultComputed,
DefaultData,
DefaultMethods,
DefaultProps,
ThisTypedComponentOptionsWithRecordProps
} from "vue/types/options";
Vue.extend({
...
} as ThisTypedComponentOptionsWithRecordProps<Vue, DefaultData<any>, DefaultMethods<any>, DefaultComputed, DefaultProps>)
