diff --git a/README.md b/README.md
index 4db0087..78b2f07 100644
--- a/README.md
+++ b/README.md
@@ -167,9 +167,6 @@ function MyComponent() {
// can pass `searchParams` from server components
const { urlState, setUrl, setState } = useUrlState({ defaultState: userState });
- // won't let you to accidently mutate state directly, requires TS
- // urlState.name = 'John' // <- error
-
return (
st);
setState((st) => ({ ...st, age: 18 }));
diff --git a/packages/example-nextjs15/src/app/Form-for-test.tsx b/packages/example-nextjs15/src/app/Form-for-test.tsx
index f332eca..e5f71e7 100644
--- a/packages/example-nextjs15/src/app/Form-for-test.tsx
+++ b/packages/example-nextjs15/src/app/Form-for-test.tsx
@@ -40,12 +40,6 @@ export const Form = ({
// Just to test ts types
if (urlState?.tags?.length === 10) {
- // @ts-expect-error should be readonly
- urlState.age = 18;
- // @ts-expect-error should be readonly
- urlState.tags[0].value = { text: 'jjj', time: new Date() };
- // @ts-expect-error should be readonly
- urlState.tags[0].value.text = 'jjj';
setState(urlState);
setState((st) => st);
setState((st) => ({ ...st, age: 18 }));
diff --git a/packages/example-react-router6/src/Form-for-test.tsx b/packages/example-react-router6/src/Form-for-test.tsx
index 14699f0..774e1bc 100644
--- a/packages/example-react-router6/src/Form-for-test.tsx
+++ b/packages/example-react-router6/src/Form-for-test.tsx
@@ -31,12 +31,6 @@ export const Form = ({ className }: { className?: string }) => {
// Just to test ts types
if (urlState?.tags?.length === 10) {
- // @ts-expect-error should be readonly
- urlState.age = 18;
- // @ts-expect-error should be readonly
- urlState.tags[0].value = { text: "jjj", time: new Date() };
- // @ts-expect-error should be readonly
- urlState.tags[0].value.text = "jjj";
setState(urlState);
setState((st) => st);
setState((st) => ({ ...st, age: 18 }));
diff --git a/packages/urlstate/next/useUrlState/README.md b/packages/urlstate/next/useUrlState/README.md
index 6aac70f..ff06376 100644
--- a/packages/urlstate/next/useUrlState/README.md
+++ b/packages/urlstate/next/useUrlState/README.md
@@ -16,7 +16,8 @@ A custom React hook that manages state and synchronizes it with URL search param
### Returns:
An object containing:
-- `urlState: object` - The current state (readonly).
+
+- `urlState: object` - The current state.
- `setState: Function` - Function to update the state without updating the URL.
- `setUrl: Function` - Function to update both the state and the URL.
diff --git a/packages/urlstate/next/useUrlState/useUrlState.ts b/packages/urlstate/next/useUrlState/useUrlState.ts
index 6bced38..1cfc576 100644
--- a/packages/urlstate/next/useUrlState/useUrlState.ts
+++ b/packages/urlstate/next/useUrlState/useUrlState.ts
@@ -5,7 +5,6 @@ import React from "react";
import { parseSPObj } from "../../parseSPObj";
import { useUrlStateBase } from "../../useUrlStateBase";
import {
- type DeepReadonly,
filterUnknownParams,
filterUnknownParamsClient,
isSSR,
@@ -115,11 +114,11 @@ export function useUrlState({
* @deprecated use `setUrl`
*/
updateUrl,
- urlState: state as DeepReadonly,
+ urlState: state,
/**
* @deprecated use `urlState`
*/
- state: state as DeepReadonly,
+ state,
getState,
};
}
diff --git a/packages/urlstate/react-router/useUrlState/README.md b/packages/urlstate/react-router/useUrlState/README.md
index 03fdbf2..363f664 100644
--- a/packages/urlstate/react-router/useUrlState/README.md
+++ b/packages/urlstate/react-router/useUrlState/README.md
@@ -16,7 +16,8 @@ A custom React hook that manages state and synchronizes it with URL search param
### Returns:
An object containing:
-- `urlState: object` - The current state (readonly).
+
+- `urlState: object` - The current state.
- `setState: Function` - Function to update the state without updating the URL.
- `setUrl: Function` - Function to update both the state and the URL.
diff --git a/packages/urlstate/react-router/useUrlState/useUrlState.ts b/packages/urlstate/react-router/useUrlState/useUrlState.ts
index ff49925..24f76a9 100644
--- a/packages/urlstate/react-router/useUrlState/useUrlState.ts
+++ b/packages/urlstate/react-router/useUrlState/useUrlState.ts
@@ -9,7 +9,6 @@ import { parseSPObj } from "../../parseSPObj";
import { useUrlStateBase } from "../../useUrlStateBase";
import {
assignValue,
- type DeepReadonly,
filterUnknownParams,
filterUnknownParamsClient,
type JSONCompatible,
@@ -121,11 +120,11 @@ export function useUrlState({
* @deprecated use `setUrl`
*/
updateUrl,
- urlState: state as DeepReadonly,
+ urlState: state,
/**
* @deprecated use `urlState`
*/
- state: state as DeepReadonly,
+ state,
getState,
};
}
diff --git a/packages/urlstate/useSharedState/README.md b/packages/urlstate/useSharedState/README.md
index 88f2ce5..76580bd 100644
--- a/packages/urlstate/useSharedState/README.md
+++ b/packages/urlstate/useSharedState/README.md
@@ -14,7 +14,8 @@ A custom React hook that manages shared state across components.
### Returns:
An object containing:
-- `state: T` - The current state (readonly).
+
+- `state: T` - The current state.
- `getState: () => T` - Function to get the current state.
- `setState: T | Partial | (T) => void` - Function to update the state.
@@ -42,7 +43,7 @@ Updates the shared state.
### Parameters:
-- `value: T | DeepReadonly | ((currState: T) => T)` - New state value or a function that receives the current state and returns the new state.
+- `value: T | ((currState: T) => T)` - New state value or a function that receives the current state and returns the new state.
## `getState`
diff --git a/packages/urlstate/useSharedState/useSharedState.ts b/packages/urlstate/useSharedState/useSharedState.ts
index 62bea33..89ef9d1 100644
--- a/packages/urlstate/useSharedState/useSharedState.ts
+++ b/packages/urlstate/useSharedState/useSharedState.ts
@@ -2,12 +2,7 @@ import React from "react";
import { stateMap, subscribers } from "../subscribers";
import { useInsertionEffect } from "../useInsertionEffect";
-import {
- type DeepReadonly,
- isEqual,
- isSSR,
- type JSONCompatible,
-} from "../utils";
+import { isEqual, isSSR, type JSONCompatible } from "../utils";
/**
* Custom React hook for sharing state between unrelated components.
@@ -51,7 +46,7 @@ export function useSharedState(
const setState = React.useCallback(
(
value:
- | (Partial | Partial>)
+ | Partial
| ((currState: typeof stateShape.current) => typeof stateShape.current),
): void => {
const curr = stateMap.get(stateShape.current);
diff --git a/packages/urlstate/useUrlStateBase/README.md b/packages/urlstate/useUrlStateBase/README.md
index ba973c1..ef85a31 100644
--- a/packages/urlstate/useUrlStateBase/README.md
+++ b/packages/urlstate/useUrlStateBase/README.md
@@ -15,7 +15,8 @@ A custom React hook to create custom `useUrlState` hooks.
### Returns:
An object containing:
-- `state: object` - The current state (readonly).
+
+- `state: object` - The current state.
- `getState: Function` - Function to get state.
- `updateState: Function` - Function to update the state without updating the URL.
- `updateUrl: Function` - Function to update both the state and the URL.
diff --git a/packages/urlstate/useUrlStateBase/useUrlStateBase.ts b/packages/urlstate/useUrlStateBase/useUrlStateBase.ts
index 76c9391..99b95dc 100644
--- a/packages/urlstate/useUrlStateBase/useUrlStateBase.ts
+++ b/packages/urlstate/useUrlStateBase/useUrlStateBase.ts
@@ -4,7 +4,6 @@ import { useInsertionEffect } from "../useInsertionEffect";
import { useSharedState } from "../useSharedState";
import { useUrlEncode } from "../useUrlEncode";
import {
- type DeepReadonly,
filterUnknownParamsClient,
type JSONCompatible,
type Router,
@@ -110,7 +109,7 @@ export function useUrlStateBase(
return {
updateState: setState,
updateUrl,
- state: state as DeepReadonly,
+ state,
getState,
};
}
diff --git a/packages/urlstate/utils.ts b/packages/urlstate/utils.ts
index 1e7887f..8698c1b 100644
--- a/packages/urlstate/utils.ts
+++ b/packages/urlstate/utils.ts
@@ -49,16 +49,6 @@ export type JSONCompatible = {
[prop: string]: JSON | JSON[];
};
-// Always will be some compromise between how strict checks are and readability
-export type DeepReadonly =
- T extends Map
- ? ReadonlyMap, DeepReadonly>
- : T extends Set
- ? ReadonlySet>
- : T extends object
- ? { readonly [K in keyof T]: DeepReadonly }
- : T;
-
export const getParams = (strOrSearchParams?: string | URLSearchParams) =>
new URLSearchParams(
typeof strOrSearchParams === "string"