Harshal Patil
Harshal Patil

Reputation: 21030

How to specify non-reactive instance property in Vue.js using TypeScript?

I am migrating my Vue.js components to TypeScript. Following the guide, I tried to use Vue.extend() for my component. My component is:

import Vue from 'vue';

const Component = Vue.extend({
  // type inference enabled
  
  created() {
    // `y` is non-reactive property
    this.y = 20; // TYPESCRIPT THROWS ERROR
  }
  
  data() {
     return {
        // x is reactive property
        x: 10
     };
  }

});

In above example, I have property x which is reactive and y as non-reactive property. However, I just cannot get type inference working for property y due the way augmentation works in TypeScript.

I cannot use simple object export for defining my component as it starts throwing a type error for both y and x.

For, now I am sticking to keeping this file as JS or move my code vue-class-component which enable me to handle this. However, I am reluctant to move to vue-class-component as it is a code at a library level.

Any solution to how I can make TypeScript happy?

Upvotes: 15

Views: 2537

Answers (3)

Andrey Ivlev
Andrey Ivlev

Reputation: 85

Solution without function wrapper

Vue.extend({
  data() {
    const reactive = {
      name: 'Jack Sparrow',
    }

    return reactive as typeof reactive & {
      nonReactiveProperty: string;
    }
  },
})

Upvotes: 1

Andrey Shchekin
Andrey Shchekin

Reputation: 21619

A simplest solution would be something like this:

  data() {
     return {
        // x is reactive property
        x: 10
     } as any as { x: number; y: number };
  }

however that requires you to explicitly define all properties of data.


Alternatively, you can do it with the following helper:

function withNonReactive<TData>(data: TData) {
    return <TNonReactive>() => data as TData & TNonReactive;
}

Like this:

  data() {
     return withNonReactive({
        // x is reactive property
        x: 10
     })<{
        // non-reactive properties go here
        y: number
     }>();
  }

Upvotes: 6

gardarh
gardarh

Reputation: 3224

One way to get rid of TypeScript errors this is by defining the following property:

data() {
    return {
       nonReactive: {} as any
    }
}

and then just add your non-reactive properties to this object in created().

created() {
    this.nonReactive.foo = {}
}

Another method I haven't really explored would be to create a typescript shim file for your component.

Upvotes: 3

Related Questions