[Vuejs]-How to solve the Type 'string' is not assignable to type '"AOI" | "DIMM" | "FAN" | undefined' ts error

2👍

You could extract the strings into a type (as pointed out by @Alexey’s answer), and export the type from the component so that callers can use it to declare their kind bindings:

<!-- MyComponent.vue -->
<script lang="ts">
import { defineComponent, type PropType } from 'vue';

export type KindType = 'AOI' | 'DIMM' | 'FAN'

export default defineComponent({
  props: {
    kind: { type: String as PropType<KindType> }
  },
})
</script>

Callers of this component could use type assertion (ref('myString' as KindType)) to tell TypeScript to treat any string as a KindType, as seen below. A disadvantage here is this allows invalid strings (i.e., not one of the KindType strings), which could lead to unexpected behavior.

<!-- App.vue -->
<script setup lang="ts">
import { ref } from 'vue'
import MyComponent, { type KindType } from './components/MyComponent.vue'

const kind = ref('foo' as KindType) // ⛔️ compiles but allows any string
</script>

<template>
  <MyComponent :kind="kind" />
</template>

A more robust solution is to pass a type argument to ref, using ref<KindType>('myString'). This enables a helpful compiler error when the string value is invalid.

<script setup lang="ts">
import { ref } from 'vue'
import MyComponent, { type KindType } from './components/MyComponent.vue'

const kind = ref<KindType>('FAN') // ✅ allows only KindType strings
</script>

<template>
  <MyComponent :kind="kind" />
</template>

demo

👤tony19

2👍

Is there not a way I can handle this issue on the frontend?

To be clear, I am not suggesting a change in the backend itself, but in the place you specify its signatures in the frontend.

But if you don’t want to change that, you can just add a type assertion someBackendMethod(...) as "AOI" | "DIMM | "FAN". Basically saying "I know that this particular string is one of these 3 even if the compiler doesn’t". But the problem is that if the backend then changes so it actually has another possible value, the compiler won’t tell you this place needs to be changed.

Another advice is to give some name to this union:

type SomeName = "AOI" | "DIMM | "FAN"

and then

kind: { type: String as PropType<SomeName> }

someBackendMethod(...) as SomeName

so at least if values are added/removed you only need to change one place.

Leave a comment