2
2
import { safeLocalStorage , Storage } from '@toss/storage' ;
3
3
import { SetStateAction , useCallback , useState } from 'react' ;
4
4
5
- export type Serializable = string | number | boolean | unknown [ ] | Record < string , unknown > ;
5
+ type ToPrimitive < T > = T extends string ? string : T extends number ? number : T extends boolean ? boolean : never ;
6
+ type ToObject < T > = T extends unknown [ ] | Record < string , unknown > ? T : never ;
7
+
8
+ export type Serializable < T > = T extends string | number | boolean ? ToPrimitive < T > : ToObject < T > ;
9
+
6
10
interface StorageStateOptions < T > {
7
11
storage ?: Storage ;
8
- defaultValue ?: T ;
12
+ defaultValue ?: Serializable < T > ;
9
13
}
10
14
11
15
interface StorageStateOptionsWithDefaultValue < T > extends StorageStateOptions < T > {
12
- defaultValue : T ;
16
+ defaultValue : Serializable < T > ;
13
17
}
14
18
15
19
/**
16
20
* 스토리지에 상태값을 저장하고 불러와서 값이 보존되는 useState로 동작하는 hook입니다.
17
21
* @param key 스토리지에 저장할 키
18
22
*/
19
- export function useStorageState < T extends Serializable > (
23
+ export function useStorageState < T > (
20
24
key : string
21
- ) : readonly [ T | undefined , ( value : SetStateAction < T | undefined > ) => void , ( ) => void ] ;
22
- export function useStorageState < T extends Serializable > (
25
+ ) : readonly [ Serializable < T > | undefined , ( value : SetStateAction < Serializable < T > | undefined > ) => void , ( ) => void ] ;
26
+ export function useStorageState < T > (
23
27
key : string ,
24
28
{ storage, defaultValue } : StorageStateOptionsWithDefaultValue < T >
25
- ) : readonly [ T , ( value : SetStateAction < T > ) => void , ( ) => void ] ;
26
- export function useStorageState < T extends Serializable > (
29
+ ) : readonly [ Serializable < T > , ( value : SetStateAction < Serializable < T > > ) => void , ( ) => void ] ;
30
+ export function useStorageState < T > (
27
31
key : string ,
28
32
{ storage, defaultValue } : StorageStateOptions < T >
29
- ) : readonly [ T | undefined , ( value : SetStateAction < T | undefined > ) => void , ( ) => void ] ;
30
- export function useStorageState < T extends Serializable > (
33
+ ) : readonly [ Serializable < T > | undefined , ( value : SetStateAction < Serializable < T > | undefined > ) => void , ( ) => void ] ;
34
+ export function useStorageState < T > (
31
35
key : string ,
32
36
{ storage = safeLocalStorage , defaultValue } : StorageStateOptions < T > = { }
33
- ) : readonly [ T | undefined , ( value : SetStateAction < T | undefined > ) => void , ( ) => void ] {
37
+ ) : readonly [ Serializable < T > | undefined , ( value : SetStateAction < Serializable < T > | undefined > ) => void , ( ) => void ] {
34
38
const getValue = useCallback ( < T > ( ) => {
35
39
const data = storage . get ( key ) ;
36
40
@@ -52,10 +56,10 @@ export function useStorageState<T extends Serializable>(
52
56
}
53
57
} , [ defaultValue , key , storage ] ) ;
54
58
55
- const [ state , setState ] = useState < T | undefined > ( getValue ) ;
59
+ const [ state , setState ] = useState < Serializable < T > | undefined > ( getValue ) ;
56
60
57
61
const set = useCallback (
58
- ( value : SetStateAction < T | undefined > ) => {
62
+ ( value : SetStateAction < Serializable < T > | undefined > ) => {
59
63
setState ( curr => {
60
64
const nextValue = typeof value === 'function' ? value ( curr ) : value ;
61
65
0 commit comments