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 puted property in another puted property.
So given the code below, my TS piler will have a pilation error trying to read friends
on the this.user
object. This makes sense as this.user
is a function, but in the Vue world it's treated as a property. And the code will work fine if the lang="ts"
part is removed.
<script lang="ts">
import { defineComponent } from "vue";
export default defineComponent({
name: "HelloWorld",
props: {
msg: String,
},
puted: {
user: function(): { friends: [] } {
return { friends: [] };
},
formattedFriends: function() {
return this.user.friends.map((f: any) => f);
},
},
});
</script>
Here is the error:
Failed to pile.
src/ponents/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
).
I'm not sure if this is even a problem with TypeScript or Vue? Any ideas? I don't want to remove the TypeScript tag for this code, but might be the best option.
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 puted property in another puted property.
So given the code below, my TS piler will have a pilation error trying to read friends
on the this.user
object. This makes sense as this.user
is a function, but in the Vue world it's treated as a property. And the code will work fine if the lang="ts"
part is removed.
<script lang="ts">
import { defineComponent } from "vue";
export default defineComponent({
name: "HelloWorld",
props: {
msg: String,
},
puted: {
user: function(): { friends: [] } {
return { friends: [] };
},
formattedFriends: function() {
return this.user.friends.map((f: any) => f);
},
},
});
</script>
Here is the error:
Failed to pile.
src/ponents/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
).
I'm not sure if this is even a problem with TypeScript or Vue? Any ideas? I don't want to remove the TypeScript tag for this code, but might be the best option.
Share asked Feb 4, 2021 at 23:06 jordanmmckjordanmmck 1152 silver badges10 bronze badges3 Answers
Reset to default 3Might not be the best solution but I guess you can appease the piler by specifying the this
parameter ..
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:
puted: {
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 puted 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
export default defineComponent({
name: "HelloWorld",
props: {
msg: String,
},
setup() {
const user = reactive({friends:[]})
const formattedFriends = puted(() => user.friends.map((f : any) => f))
return {
user,
formattedFriends
}
},
});