1
votes

Use component with template multiple times in Vue with TypeScript

My goal is to use a component with a template multiple times in another component. Codes are separated in a .html and in a .ts file.

The .html looks like this:

<template>
    <div id="app">
        <inner-component></inner-component>
        <hr />
        <inner-component></inner-component>
        <hr />
        <inner-component></inner-component>
    </div>
</template>

<script src="./componenttest.ts"></script>

While the .ts is something like this:

import Vue from 'vue';
import { Component } from 'vue-property-decorator';

export interface IStatus extends Vue {
    status: string;
}

var InnerComponent = Vue.extend({
    template: '<p>Server Status: {{ status }}(<button @click="changeStatus">Change</button>)</p>'
})

@Component({
    data: function (): IStatus {
        return { status: 'Critical'}
    },
    components: { InnerComponent },
    methods: {
        changeStatus: function (): void {
            this.status = 'Normal';
        }
    }
})
export default class ComponentTestComponent extends Vue {
}

Running the project results in these error messages:

ERROR in [at-loader] TS2322: Type '{ status: string; }' is not assignable to type 'IStatus'.

ERROR in [at-loader] TS2322: Type '{ status: string; }' is not assignable to type 'IStatus'. Property '$data' is missing in type '{ status: string; }'.

ERROR in [at-loader] TS2339: Property 'status' does not exist on type 'Vue'.

If I remove the IStatus interface mark in the data tag the only error message I got is:

ERROR in [at-loader] TS2339: Property 'status' does not exist on type 'Vue'.

I've tried to implement my interface in the ComponentTestComponent, but the error is still the same.

My guess is, that the interface lacks some details, so TypeScript doesn't generate it. In the end the Vue instance can't reach the status property because of this.

2
Don't use the @Component object for things that should be inside the class definition (data and methods).tony19
Thanks the advice, I'll keep that in mind, but the main problem is this error message: ERROR in [at-loader] TS2339: Property 'status' does not exist on type 'Vue'.Sarun

2 Answers

0
votes

The compilation error is occurring because the IStatus interface is extending Vue and the Vue interface requires much more than just a "status" property.

Try this:

export interface IStatus {
    status: string;
}
0
votes

It seems that this piece of code was missing:

declare module 'vue/types/vue' {
    interface Vue {
        status: string
    }
}

This is required for extend the Vue instance with additional properties.

To be honest the documentation contains this, just I wasn't sure about the usage for this scenario.

https://vuejs.org/v2/guide/typescript.html#Augmenting-Types-for-Use-with-Plugins