Subscribe on changes!

Union types aren't unwrapped

avatar
Jun 22nd 2021

Version

3.1.1

Reproduction link

https://github.com/jods4/volar-starter/tree/issue-260

Steps to reproduce

Expose a ComputedRef<number> | undefined to a template. Look a the type of that variable in template (e.g. with Volar)

What is expected?

The variable should be typed as number | undefined because of automatic unwrapping.

What is actually happening?

It's still ComputedRef<number> | number


See original issue at https://github.com/johnsoncodehk/volar/issues/260 for full context

avatar
Jun 22nd 2021

It does work in Vue:

Screenshot 2021-06-22 at 10 43 48

it also works with UnwrapRef type

avatar
Jun 22nd 2021

@johnsoncodehk what do you think? Is the problem in Vue or Volar?

avatar
Jun 22nd 2021

dobule does not unwrap by defineComponent.

const Comp = defineComponent({
    setup() {
        const count = ref(0)
        const double = Math.random() < 0.5 ? computed(() => count.value * 2) : undefined;
        return { count, double }
    }
})
const comp = new Comp()
type TDobule = typeof comp.double // type TDobule = ComputedRef<number> | undefined
avatar
Jul 9th 2021

@posva can you please re-open this? At first I had issues inside Volar, so I was unsure where the problem was, but now I'm seeing similar errors in my build that fails because of this.

@johnsoncodehk's last comment showed one repro of this issue.

In my project, the following fails to compile:

<!-- Comp.vue -->
<script setup lang="ts">
  defineProps<{ x: string | Promise<string> }>()
</script>

<!-- Main.vue -->
<template>
  <my-comp :x="value" />
</template>

<script setup lang="ts">
  import MyComp from "./Comp.vue";
  // shallowRef so that compiler emits _unref and not .value
  import { shallowRef } from "vue"; 
  
  let value: shallowRef<string | Promise<string>>("");
</script>

Compilation fails with Ref<string> | Ref<Promise<string>> is not assignable to parameter of type string | Promise<string>. The code runs fine but the issue is that _unref(value) is still Ref<string> | Ref<Promise<string>> when it should actually be string | Promise<string>.

Volar errors are inconvenient but not blocking. TS compilation errors make builds fail.