Collectives™ on Stack Overflow

Find centralized, trusted content and collaborate around the technologies you use most.

Learn more about Collectives

Teams

Q&A for work

Connect and share knowledge within a single location that is structured and easy to search.

Learn more about Teams

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

Ask Question

I'm working on a vue3 project with TS and come across this error:

I have 3 potential values coming from my backend and my kind prop is looking for one of those 3 values as a string.

The prop itself looks like: kind: { type: String as PropType<'AOI' | 'DIMM' | 'FAN'> }

Any idea as to why this error happens? The backend will only ever send one of those 3 values anyway, so I would assume this wouldn't be an issue.

Please let me know if you need anymore context!

Cheers!

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>
                Thanks for the detailed explaination Tony! I actually didn't realize that it would accept any string and sure enough, when I took a peek at what was coming back from the backend, sure enough, they were lower case and not the upper case I had written in my type. Cheers for that compound explanation!
– LovelyAndy
                Jun 10, 2022 at 13:29

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.

Thanks for contributing an answer to Stack Overflow!

  • Please be sure to answer the question. Provide details and share your research!

But avoid

  • Asking for help, clarification, or responding to other answers.
  • Making statements based on opinion; back them up with references or personal experience.

To learn more, see our tips on writing great answers.