Deal with TypeScript DeepReadonly state everywhere

275 Views Asked by At

I'm using simple Vue 3 Composition API stores to centralize the state of modules. After recommended good practices, the state is exported as readonly to prevent unwanted state mutation from the outside, being mutable only through the methods exported by the same store.

import { reactive, readonly } from 'vue';

const state = reactive<State>({
  /* whatever here */
});

export default readonly(state);

/* Export methods to mutate state */

After this the type of my state is deeply nested readonly everywhere. From now on, I need to add the DeepReadonly modifier to EVERY function parameter, reducer or component prop where I use the state, specially when the chain of function calls is getting deep as well. Honestly it's becoming a though task to handle it.

Not to mention passing the state as a parameter to a third party function that is not accepting DeepReadonly. Even trying to cast it, TypeScript complains mutable type can't be assigned to immutable values.

What is the proper way to deal with this? I'm soriously considering to remove the readonly protection if I can't find a way.

1

There are 1 best solutions below

0
wobsoriano On

You would use DeepReadonly and UnwrapNestedRefs both of which can be imported in vue:

import type { DeepReadonly, Ref, UnwrapNestedRefs } from 'vue';

DeepReadonly<UnwrapNestedRefs<Ref<User[]>>>

More info https://vuejs.org/api/reactivity-core.html#readonly