const test = computed(() => {
return { asdf: 5 };
});
test.value.asdf = 6;
Currently the return type for computed is Readonly<Ref<Readonly<T>>>, so last line gives me an error saying that "asdf" is a read-only property.
It should be just Readonly<Ref<T>> so that the "value" isn't writable, but there's no reason for the actual object it returns to be readonly, it should give me exactly what i return from the computed function and whether i want it to be readonly or not should be my problem.
This is working as expected, you shouldn't modify a computed property, doing otherwise would be a hack and if you want, you can get around the typing error by using a @ts-ignore
It seems to be supported in vue-next though? https://github.com/vuejs/vue-next/blob/master/packages/reactivity/src/computed.ts
I don't see why the api should change the object I'm returning in any way.
It obviously doesn't make sense in the example i posted, but my actual use case is returning a reactive object from some reactive store state and i'm using the computed as a cached shortcut so i don't have to search the store every time. I think calling that a hack is a stretch.
I guess I'll just stick with v0.3.2 where this works for now and wait for vue3.
I have another use case in which the Readonly type seems to be a problem.
In my case, I have a computed property that returns a callback, but I cannot call it because it's declared as Readonly. Here is an example:
const propertyGetter = computed(() => {
// Property value is a callback that takes an object
// and access to a property of that object
return (object: any) => object[props.propertyName];
});
const myTestObject = { /* ... */ };
propertyGetter.value(myTestObject);
The last line throws the following error:
TS2349: This expression is not callable.
Type 'Readonly<(object: any) => any>' has no call signatures.
I had to do a cast in order to avoid the error:
const propertyGetter = computed(() => {
// Property value is a callback that takes an object
// and access to a property of that object
return (object: any) => object[props.propertyName];
}) as Readonly<Ref<(object: any) => any>>;
It can be done using an utility function as well:
function asWriteableComputed<T>(
computedProperty: Readonly<Ref<Readonly<T>>>
): Readonly<Ref<T>> {
return computedProperty;
}
const propertyGetter = asWritableComputed(computed(() => {
// Property value is a callback that takes an object
// and access to a property of that object
return (object: any) => object[props.propertyName];
}));
Having to do this seems a little tricky. It would be great if computed() returned a Readonly<Ref<T>> instead :)
Most helpful comment
It seems to be supported in vue-next though? https://github.com/vuejs/vue-next/blob/master/packages/reactivity/src/computed.ts
I don't see why the api should change the object I'm returning in any way.
It obviously doesn't make sense in the example i posted, but my actual use case is returning a reactive object from some reactive store state and i'm using the computed as a cached shortcut so i don't have to search the store every time. I think calling that a hack is a stretch.
I guess I'll just stick with v0.3.2 where this works for now and wait for vue3.