vue-async-computed-decorator
vue-async-computed-decorator copied to clipboard
Async computed getter
This PR adds support to use @AsyncComputed()
on getter methods:
@AsyncComputed()
get user(): User {
return fetch('/api/users/me')
.then(r => r.json())
.then(data => data.user) as any
}
This allows for greatly improved type-checking and IDE support for AsyncComputed.
Benefits:
- You can force the return type to be User instead of Promise<User>, which is what the eventual type will be.
- This trick is only possible with getters, because all async functions must return a Promise.
- Editors will understand
this.user.name
and will not expectthis.user().name
as is the case now. - Otherwise, the plugin works exactly the same as with async functions. All options supported.
- We can use async-computed in a mostly type-safe manner without much boilerplate.
Drawbacks:
-
await
is not allowed in getters, so you must use only.then
and.catch
- the intermediate cast to any is not type-safe, and may hide incorrect casts.
To work around these limitations, I suggest the following helper method. It is not included, but it could be if approved.
// Cast a Promise<T> to T.
// Accepts a promise or async function.
function asyncComputed<T>(promise: Promise<T> | (() => Promise<T>)): T {
return (typeof promise === 'function' ? promise() : promise) as any
}
This can be used as follows:
@AsyncComputed()
get users(): User {
return asyncComputed(fetchUserAsync()) // safely cast Promise<User> to User
}
@AsyncComputed()
get users(): User {
return asyncComputed(async () => {
return await fetchUserAsync() // using await within the getter
})
}