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

TypeScript存取LocalStorage类型断言编译正常运行时报错

问题根因
  • JSON.stringify序列化规则限制:当传入Date类型实例时,会自动调用Date的toISOString()方法,将其转为ISO格式的字符串,不会保留Date的类型信息。
  • JSON.parse反序列化时,仅能将JSON内容转换为字符串、数字、布尔、普通对象、数组、null这类基础JS类型,不会自动识别日期格式字符串并转回Date实例。
  • 代码中使用的<ILocalStorageReturnValue<T>>是TypeScript的类型断言,仅在编译阶段做类型声明骗过类型检查器,不会产生任何运行时的类型转换逻辑,因此编译无报错但运行时storageDate实际是字符串类型,调用Date实例方法自然会抛出异常。
  • 额外语法问题:调用代码里误把storageDate属性当成方法加了()调用,就算类型正确也会报不是函数的错误。
正确实现逻辑

核心修复点:

  • 避免重复调用JSON.parse,减少性能损耗和异常概率
  • 反序列化完成后,手动将storageDate字段的字符串传入new Date()构造,还原为真实的Date实例
  • 增加JSON解析异常捕获,处理localStorage中存储损坏内容的边界情况
  • 调用时去掉属性名后的多余括号,做好空值判断

修正后的完整类代码:

export interface ILocalStorageReturnValue<T>{
  storageDate: Date;
  storedObj: T
}

export class LocalStorage<T> {
  constructor(){
    if(!window.localStorage) {
      throw new Error(`[${constants.FrameWorkName}.LocalStorage]:${strings.ErrBrowserNoLclStrg}`)
    }
  }

  public setItem(key: string, val: T): void {
    if(!key || !val) {
      throw new Error(`[${constants.FrameWorkName}.LocalStorage.setItem]:${strings.ErrMissingKeyValProp}`)
    }
    const saveObj: ILocalStorageReturnValue<T> = {
      storedObj: val,
      storageDate: new Date()
    }
    window.localStorage.setItem(key, JSON.stringify(saveObj))
  }

  public getItem(key: string): ILocalStorageReturnValue<T> | null {
    const rawStr = window.localStorage.getItem(key)
    if(!rawStr) return null

    try {
      const parsedResult = JSON.parse(rawStr)
      // 手动还原Date类型,保证运行时类型匹配
      return {
        storedObj: parsedResult.storedObj as T,
        storageDate: new Date(parsedResult.storageDate)
      }
    } catch (err) {
      // 存储内容损坏时清除无效缓存,返回空
      window.localStorage.removeItem(key)
      return null
    }
  }
}

正确调用示例:

const storageInstance = new LocalStorage<IImage>()
const storedData = storageInstance.getItem(constants.localStorageKey)
// 先做空值判断,再访问属性,注意storageDate是属性不是方法,不要加()
if(storedData) {
  console.log(storedData.storageDate.toDateString())
}

补充说明:如果你存储的泛型T内部本身也包含Date类型的字段,需要在反序列化时递归遍历对象,将对应日期字段手动还原为Date实例,JSON原生序列化/反序列化能力不支持自动处理这类复杂类型转换。

内容的提问来源于stack exchange,提问作者punjabi

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.08.30 22:39:12