简体   繁体   English

Vue3:使用 TypeScript 时无法从另一个计算道具访问计算道具

[英]Vue3: cannot access computed prop from another computed prop when using TypeScript

I have a Vue3 project with TypeScript, and I'm finding I cannot access the properties (using dot notation or named indexing) of the returned JS object from one computed property in another computed property.我有一个带有 TypeScript 的 Vue3 项目,我发现我无法从另一个计算属性中的一个计算属性访问返回的 JS object 的属性(使用点表示法或命名索引)。

So given the code below, my TS compiler will have a compilation error trying to read friends on the this.user object.所以给定下面的代码,我的 TS 编译器在试图读取this.user object 上的friends时会出现编译错误。 This makes sense as this.user is a function, but in the Vue world it's treated as a property.这是有道理的,因为this.user是 function,但在 Vue 世界中,它被视为属性。 And the code will work fine if the lang="ts" part is removed.如果删除lang="ts"部分,代码将正常工作。

<script lang="ts">
import { defineComponent } from "vue";

export default defineComponent({
  name: "HelloWorld",
  props: {
    msg: String,
  },
  computed: {
    user: function(): { friends: [] } {
      return { friends: [] };
    },
    formattedFriends: function() {
      return this.user.friends.map((f: any) => f);
    },
  },
});
</script>

Here is the error:这是错误:

Failed to compile.

src/components/HelloWorld.vue:92:24
TS2339: Property 'friends' does not exist on type '() => { friends: never[]; }'.
    90 |     },
    91 |     formattedFriends: function() {
  > 92 |       return this.user.friends.map((f: any) => f);
       |                        ^^^^^^^
    93 |     },
    94 |   },
    95 | });

I created this sample code with the Vue cli ( vue create ).我使用 Vue cli ( vue create ) 创建了这个示例代码。

I'm not sure if this is even a problem with TypeScript or Vue?我不确定这是否是 TypeScript 或 Vue 的问题? Any ideas?有任何想法吗? I don't want to remove the TypeScript tag for this code, but might be the best option.我不想删除此代码的 TypeScript 标记,但可能是最佳选择。

Might not be the best solution but I guess you can appease the compiler by specifying the this parameter..可能不是最好的解决方案,但我想您可以通过指定this参数来安抚编译器。

formattedFriends: function(this: any) { // or a stricter type if you wish
  return this.user.friends.map((f: any) => f);
},

One way would be to convert the type before accessing it:一种方法是在访问之前转换类型:

computed: {
    user: function(): { friends: [] } {
        return { friends: [] };
    },
    formattedFriends: function() {
        const typedUser = (this.user as { friends: [] })
        
        return typedUser.friends.map((f: any) => f);
    },
},

Interested to know if there's a better way though.有兴趣知道是否有更好的方法。

not sure what your user computed is supposed to do as it has no reactive source?不确定您的用户计算应该做什么,因为它没有反应源?

however, in Vue3, its much nicer to use the reactivity API, and do something like但是,在 Vue3 中,使用反应性 API 会更好,并执行类似的操作

export default defineComponent({
  name: "HelloWorld",
  props: {
    msg: String,
  },
  setup() {
    const user = reactive({friends:[]})
    const formattedFriends = computed(() => user.friends.map((f : any) => f))
    return {
      user,
      formattedFriends
    }
  },
});

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM