Vue-meta: Typescript compiler fails when using metaInfo() function

Created on 29 Mar 2019  路  21Comments  路  Source: nuxt/vue-meta

I would like to access component data from metaInfo() function, but typescript compiler throws me an error:

export default Vue.extend({
  metaInfo() {
    return {
      title: this.name,
    };
  },
  data() {
    return {
      name: 'Bob',
      country: 'Sweden',
    };
  },
  methods: {
    sayHi() {
      console.log('Hi ' + this.name + ' from ' + this.country);
    },
  },
});

Property 'name' does not exist on type 'CombinedVueInstance>>'.

Property 'name' does not exist on type 'CombinedVueInstance>>'.

Property 'country' does not exist on type 'CombinedVueInstance>>'.

Notice that the compiler also outputs errors in the sayHi method. The errors only occurs when using this in the metaInfo() function

question typescript

Most helpful comment

@georgeboot Do you have vue-meta under types array property in tsconfig.json ? It's needed to tell TypeScript to look for vue-meta types and correctly extend Vue Component options with metaInfo.

{
  "compilerOptions": {
    "types": [
      "vue-meta"
    ]
  }
}

All 21 comments

Do you have your own types defined so typescript nows name, country are valid properties (and what their type should be)?

When I try your example it also throws an error when I use something like return this.name in sayHi

Just using default typescript setup, it should know data property types. Only when I use this in metaInfo() compiler doesn't know data properties. I could perhaps make a small repository.

Please also check the just released v2.0 release candidate as that has a lot of typescript improvements as well

Same error here, both on 1.x and 2.0.0-rc.1.

I have the following Home.vue (created using vue-cli 3):

<template>
    <div class="home">
        <img alt="Vue logo" src="../assets/logo.png" />
        <HelloWorld msg="Welcome to Your Vue.js + TypeScript App" />
    </div>
</template>

<script lang="ts">
import { Component, Vue } from 'vue-property-decorator'
import HelloWorld from '@/components/HelloWorld.vue' // @ is an alias to /src

@Component({
    components: {
        HelloWorld,
    },
    metaInfo() {
        return {
            title: 'Homepage Title',
            titleTemplate: null,
        }
    },
})
export default class Home extends Vue {}
</script>

My vscode lints the components section with the following error:

{
    "resource": "/path/to/project/src/views/Home.vue",
    "owner": "_generated_diagnostic_collection_name_#0",
    "code": "2345",
    "severity": 8,
    "message": "Argument of type '{ components: { HelloWorld: typeof HelloWorld; }; metaInfo(): { title: string; titleTemplate: null; }; }' is not assignable to parameter of type 'VueClass<Vue>'.\n  Object literal may only specify known properties, but 'components' does not exist in type 'VueClass<Vue>'. Did you mean to write 'component'?",
    "source": "Vetur",
    "startLineNumber": 13,
    "startColumn": 5,
    "endLineNumber": 15,
    "endColumn": 6
}

Additionally, when I run yarn serve, it output the following warning:

ERROR in /path/to/project/src/views/Home.vue
13:5 Argument of type '{ components: { HelloWorld: typeof HelloWorld; }; metaInfo(): { title: string; titleTemplate: null; }; }' is not assignable to parameter of type 'VueClass<Vue>'.
  Object literal may only specify known properties, but 'components' does not exist in type 'VueClass<Vue>'. Did you mean to write 'component'?
    11 |
    12 | @Component({
  > 13 |     components: {
       |     ^
    14 |         HelloWorld,
    15 |     },
    16 |     metaInfo() {
Version: typescript 3.4.5

@georgeboot I am not too experienced with TS but your error is about components, so why do you believe there is an issue with vue-meta?

@pimlie when I remove the metaInfo() section, it works fine. Just as the reporter of this issue reports.

Maybe @kevinmarrec can help out? :relaxed:

@georgeboot Do you have vue-meta under types array property in tsconfig.json ? It's needed to tell TypeScript to look for vue-meta types and correctly extend Vue Component options with metaInfo.

{
  "compilerOptions": {
    "types": [
      "vue-meta"
    ]
  }
}

@nomadoda To access and have typed this in metaInfo the only way is to have an external interface that has the shape of your data

interface MyData {
  prop: boolean
}

and then do

metaInfo(this: MyData) {}

It works better with Class components where you just have to do (this: MyClass)

Thanks for your contribution to vue-meta! This issue has been automatically marked as stale because it has not had recent activity. It will be closed if no further activity occurs. If you would like this issue to remain open:

  1. Verify that you can still reproduce the issue in the latest version of vue-meta
  2. Comment the steps to reproduce it
    Issues that are labeled as pending will not be automatically marked as stale.

@nomadoda @georgeboot Is there still an issue ?

@kevinmarrec I did not, added it now. But no luck, still getting the same linting warning.

@georgeboot Can you try restarting VSCode ? (it happens often that tsconfig.json change need a restart)

@kevinmarrec tried that as well but doesn't resolve the issue.

Can you reproduce my issue?

@georgeboot I'm not using VueCLI so please provide a repository with the issue and I'll try to fix it

@kevinmarrec Please check: https://github.com/georgeboot/eslint-error-with-vue-meta-demo/blob/master/src/App.vue#L13-L21

It's a fresh vue-cli project with minimal options (only TypeScript and eslint) and vue-meta 2.0.0-rc.2 installed.

@georgeboot I found your issue.

TypeScript does not display the correct error, the error is that titleTemplate can't be null are you're setting it to null : https://github.com/nuxt/vue-meta/blob/master/types/vue-meta.d.ts#L115

EDIT : You can just let it empty string are not define it at all if you don't need it.

The main topic of this Github issue is resolved by my answer https://github.com/nuxt/vue-meta/issues/340#issuecomment-493384790. So i'm closing it.

I'm also having this issue today. In my case, the problem seems to be base: { href: '/' } in the metaInfo's return object and { 'http-equiv': 'X-UA-Compatible', content: 'IE=edge' } in the meta array. Don't' know why though.

Please update documentation

I had the same error and was able to resolve it without declaring an interface:

import { MetaInfo } from 'vue-meta';

export default Vue.extend({
  metaInfo(): MetaInfo {
         // ^ Add the return-value type
  ...
Was this page helpful?
0 / 5 - 0 ratings