I am using Vue 3 with the Composition API, and I am currently trying to add Typescript in my project.
I have a "global input" component that I call to create whatever input I want. This component will then render another input component depending on the "inputType" props. For example, I can use the global input like this :
<InputBlock input-type="number" :value="15" :min="0" :max="100" />
<InputBlock input-type="check" :value="true" />
The InputBlock looks something like this :
<script setup lang="ts">
import InputNumber from "./InputNumber.vue"
import InputCheck from "./InputCheck.vue"
const props = defineProps({
value: { type: [Boolean, Number], required: true }, // Here the value can be type Boolean|Number
inputType: { type: String, required: true },
// ...
})
</script>
<template>
<InputCheck v-if="intputType === 'check'" :value="value" />
<InputNumber v-if="intputType === 'number'" :value="value" /> <!-- Here it is supposed to be Number -->
</template>
And my InputNumber
looks something like this :
<script setup lang="ts">
const props = defineProps({
value: { type: Number, required: true },
// ...
}}
</script>
As you can notice, the InputBlock
component can receive a value with different types, since this value will be use by different subcomponents. But each subcomponent can accept only one type for its value
props. In my InputBlock
I get this error : Type 'number | boolean' is not assignable to type 'number'. Type 'boolean' is not assignable to type 'number'.
.
Do you have any idea how I can tell Typescript that the value passed in the InputCheck
will be a Number and not Number|Boolean ? Is there a way to "force" ou "cast" the variable ? Or am doing something wrong here ?
CodePudding user response:
its return an error because typescript don't know that inputType.type and the value type are related.
you can try thy
<template>
<InputCheck v-if="typeof value === 'boolean'" :value="value" />
<InputNumber v-if="typeof value === 'number'" :value="value" /> <!-- Here it is supposed to be Number -->
</template>
or this
<script setup lang="ts">
import InputNumber from "./InputNumber.vue"
import InputCheck from "./InputCheck.vue"
const props = defineProps({
value: { type: [Boolean, Number], required: true }, // Here the value can be type Boolean|Number
})
const isBoolean = (value: any) => typeof value === "boolean"
const isNumber = (value: any) => typeof value === "number"
</script>
<template>
<InputCheck v-if="isBoolean(value)" :value="value" />
<InputNumber v-else-if="isNumber(value)" :value="value" /> <!-- Here it is supposed to be Number -->
</template>