typescriptvue.jsvuejs3

‘Type Ref<…> is not assignable to type Ref<T>’


I am making a website using Vue and Typescript and am getting an unexpected error in TypeScript, which I honestly have no idea how to fix. Basically, I have a Spawner component, which when clicked, spawns a SpawnerItem and passes some properties as a reference, so that it can change them and show these changes in the original Spawner. Here is the interface for the properties (they have to be ref, so they can be modified):

export interface UseDraggable {
  x: Ref<number>
  y: Ref<number>
  isDragging: ComputedRef<boolean>
  style: ComputedRef<string>
  startDrag: () => void
}

I have a map to store the properties of all items:

const draggables = ref(new Map<string, Ref<UseDraggable>>())

But when I try to set the data for an item in the map:

const defaultUseDraggable: Ref<UseDraggable> = ref({
  x: ref(0),
  y: ref(0),
  isDragging: computed(() => false),
  style: computed(() => 'left:0px;top:0px;'),
  startDrag: () => {}
})

draggables.value.set(id, defaultUseDraggable)

I get the error:

Type 'Ref<{ x: number; y: number; isDragging: boolean; style: string; startDrag: () => void; }>' is not assignable to type 'Ref<UseDraggable>'.
  Type '{ x: number; y: number; isDragging: boolean; style: string; startDrag: () => void; }' is not assignable to type 'UseDraggable'.
    Types of property 'x' are incompatible.
      Type 'number' is not assignable to type 'Ref<number>'.

I tried setting the defaultUseDraggable to computed, instead of a ref and it sets the data successfully. But then I can't modify the properties, which is the whole idea of this. I have also tried not wrapping it in a ref and then it recognized it as a variable of type UseDraggable, but the map required is to be Ref<UseDraggable> and so if I put ref in the set function of the map, it gives me an error again.


Solution

  • Refs within refs get unwrapped. That's why typescript expects the inner value types.

    interface UseDraggable {
      x: number
      y: number
      isDragging: boolean
      style: string
      startDrag: () => void
    }