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

Typescript: incorrect typings for unwrapped refs #3315

Closed
shameleo opened this issue Feb 26, 2021 · 6 comments · Fixed by #3319
Closed

Typescript: incorrect typings for unwrapped refs #3315

shameleo opened this issue Feb 26, 2021 · 6 comments · Fixed by #3319
Labels
🔨 p3-minor-bug Priority 3: this fixes a bug, but is an edge case that only affects very specific usage. 🐞 bug Something isn't working scope: types

Comments

@shameleo
Copy link

Version

3.0.6

Reproduction link

https://github.com/shameleo/vue-ts-bug

Steps to reproduce

npm install
npm run dev

Open index.html browser and look console output.

What is expected?

If typescript is correct, console.log would print refs and their values.

What is actually happening?

I see values and undefined


Here essential code:

export default defineComponent({
  data: () => ({
    arr: [1, 2, 3].map((num) => ({ num: ref(num) })),
  }),
  mounted() {
    this.arr.forEach((el) => {
      console.log(el.num);
      // Typescript shows it is Ref<number>, but actually it is number
      console.log(el.num.value);
    });
  },
});
@edison1105
Copy link
Member

edison1105 commented Feb 26, 2021

It's not a bug.this is intentional in options api.

you will see your expected use setup:

  setup(){
    const arr = [1, 2, 3].map((num) => ({ num: ref(num) }))
    arr.forEach((el) => {
      console.log(el.num);
      console.log(el.num.value);
    });
  }

@shameleo
Copy link
Author

shameleo commented Feb 26, 2021

If it is true than I have a lot of questions:

  1. Using refs is forbidden in optional API? I didn't see any docs or runtime warnings about it.
  2. Huge amount of tricks would be not available in optional API. Refs bound to URL params, local storage or many other use cases when some factory function returns ref or computed ref. For example, I noticed the issue, when I tried to make tree node, with checked prop as ref, which is updated when children's corresponding checked props updated. I can't do it? A HUGE dissapointment.
  3. Some libs will only can be used with composition API (for instance). And it is problem as we can't use data and methods from options API in setup, so whole component must be written in composition style.
  4. As a result, options API is second class citizen now, and it's not even matter of choice.

If 1-4 is not true, and it's actually works than why typescript should tell me it doesn't?

PS. More appropriate example of composition API would be

import { defineComponent, ref, reactive } from "vue";

export default defineComponent({
  setup() {
    const r = reactive({
      arr: [1, 2, 3].map((num) => ({ num: ref(num) }))
    });

    r.arr.forEach(el => { console.log(el.num) });
  }
});

It all about unwrapping.

PS2. Example is a bit overcomplicated (array of objects instead of simple ref) because I couldn't reproduce issue with just ref. I can now, and it's confusing. Don't know if either different IDE or different packages or whatever made the difference.

@posva
Copy link
Member

posva commented Feb 26, 2021

It should be

data: () => ({
    arr: [1, 2, 3].map((num) => ({ num })),
  }),

without ref


Please, next time consider using the forum, the Discord server or StackOverflow for questions first. But feel free to come back and open an issue if it turns out to be a bug 🙂

@posva posva closed this as completed Feb 26, 2021
@shameleo
Copy link
Author

shameleo commented Feb 26, 2021

@posva, the questions is not about how to use it right, as I need ref in real case. Some usecases is in previous post. I didn't see in docs that refs can't be used in options API. Runtime does not warn if I do it. It even seems to work. Except correct typescript support. If using refs in data is forbidden, that I would expect core maintainers to explicitly say this, not some people on forum. Because it has significant consequences (look previous post) and makes options API discouraged legacy way of writing components

@HcySunYang HcySunYang reopened this Feb 27, 2021
@LinusBorg LinusBorg added 🐞 bug Something isn't working scope: types 🔨 p3-minor-bug Priority 3: this fixes a bug, but is an edge case that only affects very specific usage. labels Feb 27, 2021
@LinusBorg
Copy link
Member

LinusBorg commented Feb 27, 2021

@posva He has a point. I don't think we have a rule of ref being forbidden in data. If we can solve this at the type level, we should.

@posva
Copy link
Member

posva commented Feb 27, 2021

In general, the Options API and the Composition API shouldn't be mixed. When using composition functions that return Refs, one should use setup(). This was mentioned in other comments but I couldn't find the right one, only this one about mixins.

However, you are both right about the types: it should properly infer it

@github-actions github-actions bot locked and limited conversation to collaborators Oct 23, 2023
Sign up for free to subscribe to this conversation on GitHub. Already have an account? Sign in.
Labels
🔨 p3-minor-bug Priority 3: this fixes a bug, but is an edge case that only affects very specific usage. 🐞 bug Something isn't working scope: types
Projects
None yet
Development

Successfully merging a pull request may close this issue.

5 participants