Skip to content

shallowRef's return type should match ref's #7852

@simlevesque

Description

@simlevesque

Vue version

3.2.47

Link to minimal reproduction

New reproduction with runtime error: codesandbox.io

typescriptlang.org

Steps to reproduce

  • Use shallowRef with a generic type params that's a union : shallowRef<{a:1} | {b:2}>({a:1})
  • Or use shallowRef and specify argument's type with as: shallowRef({a:1} as {a:1} | {b:2})

What is expected?

The return type should be ShallowRef<{a:1} | {b:2}>.

What is actually happening?

The return type is ShallowRef<{a:1}> | ShallowRef<{b:2}>

System Info

System:
    OS: Linux 6.1 Ubuntu 22.10 22.10 (Kinetic Kudu)
    CPU: (16) x64 AMD Ryzen 9 5900HX with Radeon Graphics
    Memory: 10.10 GB / 30.75 GB
    Container: Yes
    Shell: 3.5.1 - /usr/bin/fish
  Binaries:
    Node: 14.20.0 - ~/.local/share/nvm/v14.20.0/bin/node
    Yarn: 1.22.19 - ~/.local/share/nvm/v14.20.0/bin/yarn
    npm: 8.17.0 - ~/.local/share/nvm/v14.20.0/bin/npm
  Browsers:
    Chrome: 110.0.5481.177
    Firefox: 110.0.1

Any additional comments?

This breaks Vue's watch function. The first argument of watch's callback becomes a Ref instead of the value, which will cause a runtime error because Property 'value' does not exist on type '{ a: 1; } | { b: 2; }'

The reproduction link provides a good example of this. If you have any questions just ask me.

I've fixed the issue on my fork and the CI actions completed successfully.

You need to change
function shallowRef<T extends object>(value: T): T extends Ref ? T : ShallowRef<T>;

to
function shallowRef<T extends object>(value: T): [T] extends [Ref] ? T : ShallowRef<T>;

This matches ref's type:
function ref<T extends object>(value: T): [T] extends [Ref] ? T : Ref<UnwrapRef<T>>;

I think this bug is present in other parts of the code but I'm not sure right now.

Metadata

Metadata

Assignees

No one assigned

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions

      pFad - Phonifier reborn

      Pfad - The Proxy pFad of © 2024 Garber Painting. All rights reserved.

      Note: This service is not intended for secure transactions such as banking, social media, email, or purchasing. Use at your own risk. We assume no liability whatsoever for broken pages.


      Alternative Proxies:

      Alternative Proxy

      pFad Proxy

      pFad v3 Proxy

      pFad v4 Proxy