You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

如何在TypeScript中检查传入类型?实现string|undefined的JSON解析优化

如何在TypeScript中实现根据泛型类型调整useLocalStorage的解析逻辑

要实现当泛型参数T为string | undefined时跳过JSON解析/序列化的逻辑,核心要解决两个问题:编译时的类型推断和运行时的逻辑分支——因为TypeScript泛型是编译时信息,运行时无法直接读取泛型类型,所以我们需要结合传入的fallbackValue的运行时类型来做判断。

修改后的完整代码

import { useEffect, useState, Dispatch, SetStateAction } from 'react'

type SetValue<T> = Dispatch<SetStateAction<T>>

// 函数重载:明确string|undefined类型的分支
export function useLocalStorage<T extends string | undefined>(key: string, fallbackValue: T): [T, SetValue<T>]
export function useLocalStorage<T>(key: string, fallbackValue: T): [T, SetValue<T>]
export function useLocalStorage<T>(key: string, fallbackValue: T): [T, SetValue<T>] {
    const [value, setValue] = useState<T>(() => {
        if (typeof localStorage === 'undefined') {
            return fallbackValue
        }
        const stored = localStorage.getItem(key)
        if (!stored) {
            return fallbackValue
        }
        // 运行时判断:如果fallback是string或undefined,直接返回存储的字符串
        if (typeof fallbackValue === 'string' || fallbackValue === undefined) {
            return stored as T
        }
        // 其他类型执行JSON解析
        return JSON.parse(stored) as T
    })

    useEffect(() => {
        if (typeof localStorage === 'undefined') {
            return
        }
        // 保存时同理:string或undefined直接存储,其他类型序列化
        if (typeof value === 'string' || value === undefined) {
            localStorage.setItem(key, value ?? '')
        } else {
            localStorage.setItem(key, JSON.stringify(value))
        }
    }, [key, value])

    return [value, setValue]
}

关键逻辑说明

  1. 函数重载:通过重载声明,让TypeScript在传入string | undefined类型的fallbackValue时,能更准确地推断返回值类型,避免不必要的类型断言。
  2. 运行时类型判断:
    • 读取阶段:检查fallbackValue的类型,如果是string或undefined,直接返回localStorage中存储的字符串(因为此时T必然是string | undefined);否则执行JSON.parse。
    • 保存阶段:检查当前value的类型,如果是string或undefined,直接存入localStorage;否则执行JSON.stringify。
  3. 类型断言:因为我们已经通过运行时判断确保了类型匹配,所以用as T做类型断言是安全的。

使用示例

// 字符串类型:自动跳过JSON解析
const [username, setUsername] = useLocalStorage('username', 'default-name')

// 对象类型:自动执行JSON解析/序列化
const [userInfo, setUserInfo] = useLocalStorage('user-info', { id: 1, name: 'Alice' })

// undefined类型:直接存储空字符串(也可根据需求调整)
const [token, setToken] = useLocalStorage('token', undefined)

内容的提问来源于stack exchange,提问作者János

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.07.23 15:13:10