Hi I'm testing out the Vue composition API with Types
I'm trying to get an error when an interface
does not meet the types
specified for that interface.
I'm successful in implementing the interface/types that are being expected and I get auto suggestions from my IDE so it looks like it works, but when compiling I don't get any errors when trying to pass let's say a number
to a string
type.
Here I provide a simple sample
Vue file:
<template>
<div >
<h1 >Test View</h1>
<TestComponent
:dataset="{
strCustomerName: 12345,
}"
/>
</div>
</template>
<script setup lang="ts">
import TestComponent from "@/components/TestComponent.vue";
</script>
This Vue file is just importing a component and sending with it an object named dataset.
Test component
<template>
<h1 >Hello {{ props.dataset.strCustomerName }}</h1>
</template>
<script setup lang="ts">
import { defineProps } from "vue";
type FormType = {
strCustomerName: string;
};
interface FormProperties {
dataset: {
type: FormType;
required: true;
};
}
const props = defineProps<FormProperties>();
console.log("We are props: ", props.dataset);
</script>
Then with this test component, I am trying to tell Vue that I am expecting a dataset object to be passed as a property in the FormProperties
, I'm then trying to tell Vue that I want a certain structure from that object which is the FormType
where the problem in the example above is that strCustomerName
is set to be a string
but when I'm passing a number
it just goes straight through without any error. I can even pass a key that is not there like if I wanted to use the view file like this:
<template>
<div >
<h1 >Test View</h1>
<TestComponent
:dataset="{
strCustomerHasAName: 'please give me an error'
}"
/>
</div>
</template>
<script setup lang="ts">
import TestComponent from "@/components/TestComponent.vue";
</script>
So basically why am I not getting an error when passing wrong types? or keys that are not defined in the FormType
object?
Is this the normal behavior or can I actually do something about it?
CodePudding user response:
Using defineProps
The type annotation for defineProps
declares the actual type of every prop, so in your case, defineProps<FormProperties>()
tells Vue to create a prop named dataset
that has two fields:
type
, which is of typeFormType
, which has astrCustomerName
property, which is astring
.required
, which is of typetrue
(i.e., it can only betrue
, and any other value would result in an error).
It looks like you were actually trying to use the option syntax for declaring a prop, but that must be given as a function argument to defineProps
:
import type { PropType } from 'vue'
defineProps({
dataset: {
type: Object as PropType<FormType>,
required: true,
}
})
Or if you'd rather use type annotations, you need to update FormProperties
:
type FormType = {
strCustomerName: string;
};
interface FormProperties {
dataset: FormType;
}
defineProps<FormProperties>();
You can't mix the two. defineProps
receives either the type annotation, or the function argument, not both.
Detecting the error
Or if you used vue-tsc
for typechecking, you would've seen the error in the console:
$ vue-tsc --noEmit
src/components/MyComponent.vue:2:52 - error TS2339: Property 'strCustomerName' does not exist on type '{ type: FormType; required: true; }'.
2 <h1 >Hello {{ props.dataset.strCustomerName }}</h1>
~~~~~~~~~~~~~~~
Found 1 error in src/components/MyComponent.vue:2