Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

toRefs type is wrong when using defineProps with optional boolean props #5847

Closed
extrem7 opened this issue May 2, 2022 · 7 comments · Fixed by #7619
Closed

toRefs type is wrong when using defineProps with optional boolean props #5847

extrem7 opened this issue May 2, 2022 · 7 comments · Fixed by #7619

Comments

@extrem7
Copy link

extrem7 commented May 2, 2022

Version

3.2.26

Reproduction link

stackblitz.com

Steps to reproduce

import { toRefs } from 'vue'

const props = defineProps<{
  isLive?: boolean
}>()

const { isLive } = toRefs(props)

What is expected?

According to fix(runtime-core): ensure declare prop keys are always present type of isLive should be:

Ref<boolean>

What is actually happening?

The type of isLive actually is:

Ref<boolean | undefined> | undefined

isLive couldn't be undefined in no case

@liulinboyi
Copy link
Member

In this test case if the props type is Boolean, absent should cast to false.

@StephenChips
Copy link
Contributor

Interesting, I tend to think this is a bug, since other primitive type's default value is undefined.

@liulinboyi
Copy link
Member

Interesting, I tend to think this is a bug, since other primitive type's default value is undefined.

If it's a bug,it's easy to fix,change the handling of this situation

    // boolean casting
    if (opt[BooleanFlags.shouldCast]) {
      if (isAbsent && !hasDefault) {
        value = false
      } else if (
        opt[BooleanFlags.shouldCastTrue] &&
        (value === '' || value === hyphenate(key))
      ) {
        value = true
      }
    }

to

    // boolean casting
    if (opt[BooleanFlags.shouldCast]) {
      if (isAbsent && !hasDefault) {
        value = undefined
      } else if (
        opt[BooleanFlags.shouldCastTrue] &&
        (value === '' || value === hyphenate(key))
      ) {
        value = true
      }
    }

but in this test case if the props type is Boolean, absent should cast to false.

@StephenChips
Copy link
Contributor

StephenChips commented May 4, 2022

@liulinboyi

If is a not a bug, why we need this behaviour, what is the motivation of this design? It is kind of odd and inconsistent to other types. IMO, absent value should always be undefined.

I noticed that only boolean props will do the casting, other types will just remain undefined (e.g. number, string).

@extrem7
Copy link
Author

extrem7 commented May 4, 2022

@StephenChips I think there are two different moments: Ref<boolean | undefined> and Ref<> | undefined. Seems like the second has no sense (because keys are always present in props). The first case may be consistent behavior.

@ig1na
Copy link

ig1na commented Jun 14, 2022

Even when using withDefaults setting the prop to undefined, the type becomes Ref<boolean> but should be Ref<boolean | undefined>

Is there any workaround to use watchers on props without using toRefs ?

@Guebbit
Copy link

Guebbit commented Aug 24, 2022

The problem is still there, I thought it was a little ugly to put an additional check, hope it will be fixed soon

yyx990803 pushed a commit that referenced this issue Feb 2, 2023
zhangzhonghe pushed a commit to zhangzhonghe/core that referenced this issue Apr 12, 2023
IAmSSH pushed a commit to IAmSSH/core that referenced this issue May 14, 2023
@github-actions github-actions bot locked and limited conversation to collaborators Sep 15, 2023
Sign up for free to subscribe to this conversation on GitHub. Already have an account? Sign in.
Projects
None yet
6 participants