Home > Mobile >  Vue 3 : Type 'number | boolean' is not assignable to type 'number'
Vue 3 : Type 'number | boolean' is not assignable to type 'number'

Time:12-02

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>
  • Related