Subscribe on changes!

`shallowRef` value incompatible with parameter of the same type

avatar
Feb 20th 2024

Vue version

3.3.12

Link to minimal reproduction

https://stackblitz.com/edit/vue3-vite-starter-nvhwqh?file=src%2Fissue.ts

Steps to reproduce

  • Use 3.3.12

  • Create a shallowRef with a generic type that extends an interface T extends Base

  • The value of shallowRef is incompatible as a parameter to functions that accept T

  • Reproduce the same case with 3.3.11

  • There is no issue

ℹ️ This is still an issue on 3.4.x also.

What is expected?

Here I would expect the value of my shallowRef T to be compatible with T.

What is actually happening?

Argument of type 'Base | T' is not assignable to parameter of type 'T'.

System Info

System:
  OS: macOS 14.3.1
  CPU: (8) arm64 Apple M1
  Memory: 335.19 MB / 16.00 GB
  Shell: 5.9 - /bin/zsh
Binaries:
  Node: 20.11.0 - ~/.nvm/versions/node/v20.11.0/bin/node
  Yarn: 1.22.21 - ~/.nvm/versions/node/v20.11.0/bin/yarn
  npm: 10.2.4 - ~/.nvm/versions/node/v20.11.0/bin/npm
  pnpm: 8.15.1 - ~/.nvm/versions/node/v20.11.0/bin/pnpm
  bun: 1.0.15 - ~/.bun/bin/bun
  Watchman: 2023.06.12.00 - /opt/homebrew/bin/watchman
Browsers:
  Chrome: 121.0.6167.184
  Chrome Canary: 123.0.6312.0
  Edge: 121.0.2277.128
  Safari: 17.3.1
npmPackages:
  vue: ^3.3.12 => 3.3.12

Any additional comments?

Likely related to this? https://github.com/vuejs/core/pull/9839

And wondering if it's not related to this comment specifically?

But then how should I correct do what I've described? ☝️

avatar
Feb 20th 2024

Due to the fact that generics require types to be explicitly determined at their usage, unexpected types may arise within functions. It is suggested to use the following approach:

interface Base {
  start: number
}

export function useComposable<T extends Base>(callback: (value: T) => void) {
  const myRef: ShallowRef<T | null> = shallowRef(null)
  if (myRef.value) {
    callback(myRef.value)
  }
}
avatar
Feb 20th 2024

unexpected types may arise within functions

@Alfred-Skyblue do you have an example? In this case - under what circumstance could myRef.value ever be incompatible with T in this case?

avatar
Feb 21st 2024

@Alfred-Skyblue this example is for ref. shallowRef does not (at least not explicitly) return any Ref<UnwrapRef< types. Playpground

In my original reproduction case, changing shallowRef -> ref does introduce a warning about UnwapRef, but this isn't what's reported in my issue.

Also the answer you've linked, was written before version 3.3.11 (the version introducing my type issue) was released.

avatar
Feb 21st 2024

I'm just giving a similar example. Due to the uncertainty of generics, we can't guarantee that it returns the passed generic type.

avatar
Feb 21st 2024

Ok seems a bit odd - then why even offer this in the first place, if the recommendation is to cast 😅 But OK understood. I can update my code. Thanks 🙏