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 class="flex flex-col">
<h1 class="flex justify-center">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 class="text-9x1 flex">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 class="flex flex-col">
<h1 class="flex justify-center">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?
defineProps
The type declaration for defineProps
specifies only the 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 type FormType
, which has a strCustomerName
property, which is a string
.
required
, which is of type true
(i.e., it can only be true
, and any other value would result in an error).
It looks like you were actually trying to use the runtime declaration with defineProps
, 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 the type declaration, update FormProperties
to contain only the data fields:
type FormType = {
strCustomerName: string;
};
interface FormProperties {
dataset: FormType;
}
defineProps<FormProperties>();
You can't mix the two. defineProps
receives either the type declaration, or the function argument, not both.
If you used Volar (the official VS Code extension for Vue), you would've seen an error for your original code:
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 class="text-9x1 flex">Hello {{ props.dataset.strCustomerName }}</h1>
~~~~~~~~~~~~~~~
Found 1 error in src/components/MyComponent.vue:2