-
Notifications
You must be signed in to change notification settings - Fork 6
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Setup store to be readonly #21
Comments
Yes, unfortunately there is a problem with readonly types and immer. Basic setter function has But, for some reason, when these two overloads are present together in the final setter type, typescript messes up So, you need to set See examples below: import { create } from "zustand";
import { immer } from "zustand/middleware/immer";
import { withLenses, lens } from "@dhmk/zustand-lens";
import { ReadonlyDeep, WritableDeep } from "type-fest";
import { Draft, produce } from "immer";
// 1. Type lenses
type Test = ReadonlyDeep<{
id: number;
name: string;
}>;
const slice = lens<Test>((set) => {
return {
id: 1,
name: "a",
test() {
set((d) => {
// Errors, because `d` has type `Test` (ReadonlyDeep)
d.id = 1;
d.name = "a";
});
set((d: Draft<Test>) => {
d.id = 1;
d.name = "a";
});
set((d: WritableDeep<Test>) => {
d.id = 1;
d.name = "a";
});
set(
produce((d) => {
d.id = 1;
d.name = "a";
})
);
},
};
});
const store = create(immer(withLenses({ slice })));
store.getState().slice.id = 1; // Expected error
// 2. Type store
type StoreType = ReadonlyDeep<{
slice: {
id: number;
name: string;
};
}>;
const store2 = create<StoreType>()(
immer(
withLenses({
slice: lens((set) => ({
id: 1,
name: "a",
test() {
set((d) => {
// Errors, because `d` is readonly
d.id = 1;
d.name = "a";
});
set((d: Draft<Test>) => {
d.id = 1;
d.name = "a";
});
set((d: WritableDeep<Test>) => {
d.id = 1;
d.name = "a";
});
set(
produce((d) => {
d.id = 1;
d.name = "a";
})
);
},
})),
})
)
);
store2.getState().slice.id = 1; // Expected error |
I'm loving this library. We're already using it, so it's going into production.
However, I noticed that due to an error, we used a sort function (which mutates arrays), causing the application to crash because Immer prohibits mutating the store.
We replaced the usage of .sort with .toSorted, resolving the issue since .toSorted is a non-mutating method. Nevertheless, we'd like TypeScript to assist us with this in the future.
How can we ensure that the store's type is readonly? I attempted to make all lenses ReadonlyDeep (using the type-fest utility), but that seems to result in a cascade of TypeScript issues.
The text was updated successfully, but these errors were encountered: