7

I'm looking for to declare a typescript interface Props in Vuejs class Component like we can do with React Component.

It's look like this :

import {Component, Prop, Vue} from 'vue-property-decorator'

export class Props extends Vue
{
  classElement :string
}

@Component
export default class Menu extends Vue<Props>
{
    public props :Props;

    constructor(props)
    {
        super(props);
        console.log(props); // return undefined 
    }

    mounted()
    {
      console.log(this.props.classElement); // return undefined
    }
}

Is there a way to achieve this?

4 Answers 4

10

Now you can use {type: Object as () => User} inside a Prop() decorator like this:

import Vue from 'vue'
import { Component, Prop } from 'vue-property-decorator'

import User from './models/user';

@Component()
export default class Menu extends Vue
{    

    @Prop({type: Object as () => User})
    public user!: User // notice the bang saying to compiler not to warn about no initial value

    mounted(){
      console.log(this.user);
    }

}
Sign up to request clarification or add additional context in comments.

4 Comments

Your comment says notice the question mark but you're using bang. Shouldn't you use the ?; since ? means it might be undefined and ! means it definitely is not undefined?
Thanks for the spot, fixed. Actually That's the non-null assertion operator. It is a way to tell the compiler "this expression cannot be null or undefined here in contexts where the type checker is unable to conclude that fact like Vue filling that variable value later, so don't complain about the possibility of it being null or undefined.
I’m sorry. I left out the null. Correction: ‘!’ means not undefined or null. ‘?’ means or undefined.
I'm using vue 2.6.10; I did this exact syntax, the code compiles, but, if i pass a "bad" property in, the validation doesn't complain. What am I doing wrong?
5

Additionally it is now possible using the Typescript type PropType.

import Vue, { PropType } from 'vue'
import { Component, Prop } from 'vue-property-decorator'

import User from './models/user';

@Component()
export default class Menu extends Vue {    

    @Prop({type: Object as PropType<User>})
    public user!: User // notice the bang saying to compiler not to warn about no initial value

    mounted(){
      console.log(this.user);
    }

}

Comments

1

Yes, all functionality of the basic javascript vue library can be used when using typescript. I suggest you use the offical class decorator.

Defining a prop can be done by simply adding it as a parameter to your class decorator like so:

@Component({
  props: {
    classElement: String
  }
})
export default class Menu extends Vue
{
    mounted()
    {
      console.log(this.classElement);
    }
}

Because component accepts an object you can define an interface for this object and pass this in instead as well.

Alternatively you can use the vue-property-decorator for a more angular-like syntax.

2 Comments

Thanks, I knew this way of props declaration, but I would like to remain as close as possible to Typescript way. I'm not a big fan of @prop() syntax. How can I pass type the object props with Interface ? I tried props: { type : Object as () => Props } but return undefined too.
The @prop decorator is as close to the typescript way as it gets. Angular for example has a pretty similar syntax and is built from typescript from scratch, unlike vue or react. Vue's property pattern is simply different from reacts, so I assume you can't get the exact same syntax. But like I also mentioned, if you want more type-safety you can pass any instance of a class (implementing whatever interface you like) to that component decorator.
0

You can extend class with props like so:

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


const props = Vue.extend({
   classElement: {
      type: String
   }
})

@Component
export default class Menu extends props
{
    mounted() {
      console.log(this.classElement);
    }
}

Comments

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.