Props typing in Vue.js 3 with TypeScript
Solution 1
You should use it with PropType
imported from vue like Object as PropType<FlashInterface>
:
import FlashInterface from '@/interfaces/FlashInterface';
import { ref,PropType, defineComponent } from 'vue';
import { useStore } from 'vuex';
export default defineComponent({
props: {
message: {
type: Object as PropType<FlashInterface>,
required: true
}
},
setup(props) {
// Stuff
}
});
Note : you should create your component using defineComponent
in order to get the types inference.
Solution 2
The compiler is complaining about missing a reference for a (custom) constructor during type checking (links to legacy docs but works the same way with the most recent version of Vue).
In Typescript, you might want to think of interfaces as a contract that an entity should conform to, so they aren't really a constructor, and therefore, we need to provide an implementation of those interfaces.
Since you are on Typescript, if you need to keep the interface, consider using the class equivalent:
// Name the constructor whatever you like,
// but I would personally prefix interfaces with an "I"
// to distinguish them with the constructors
class Flash implements FlashInterface {
level: string;
message: string;
id?: string
constructor() {
// Be sure to initialize the values for non-nullable props
this.level = '';
this.message = '';
}
}
export default {
name: 'Home',
props: {
message: Flash
}
}
An excerpt from the doc:
In addition,
type
can also be a custom constructor function and the assertion will be made with aninstanceof
check. For example, given the following constructor function exists:
props: {
message: {
type: function Person(firstName, lastName) {
this.firstName = firstName
this.lastName = lastName
}
}
}
And of course, another alternative would be as suggested in the other post with PropType
. Either one will do. It's just a matter of preference, I guess.
Related videos on Youtube
chindit
Updated on June 04, 2022Comments
-
chindit almost 2 years
I'm trying to type hint my props in a Vue 3 component, with composition API.
So, I'm doing this:
<script lang="ts"> import FlashInterface from '@/interfaces/FlashInterface'; import { ref } from 'vue'; import { useStore } from 'vuex'; export default { props: { message: { type: FlashInterface, required: true } }, setup(props): Record<string, unknown> { // Stuff } };
My
FlashInterface
looks like this:export default interface FlashInterface { level: string, message: string, id?: string }
This interface works well except in this case where I got this error:
ERROR in src/components/Flash.vue:20:10 TS2693: 'FlashInterface' only refers to a type, but is being used as a value here. 18 | props: { 19 | message: { > 20 | type: FlashInterface, | ^^^^^^^^^^^^^^ 21 | required: true 22 | } 23 | },
I don't understand why TypeScript thinks this is a value.
What am I missing?
-
Farhod Nematov over 2 yearsWhat about if props type is array? It will be Array as PropType<FlashInterface> or Object as PropType<FleshInterface[]> ??
-
Boussadjra Brahim over 2 years@FarhodNematov it should be
type: Array as PropType<FlashInterface[]>,
ortype: Array as PropType<Array<FlashInterface>>,
-
Farhod Nematov over 2 yearsThank you. But I have problem. In my script setup part I have a props with type array. In a script setup body I want to manipulate property. so props = defineProps(messages: { type: Array as PropType<...> }); Then I want to get computed property. const a = props.messages.find(m => Here m have to be FlashInterface but idea can't know); idea can't know messages is array. I can't give me suggestions. How can I fix this issue?