【问题标题】:How to cast a plain object as a instance of another type in JavaScript如何在 JavaScript 中将普通对象转换为另一种类型的实例
【发布时间】:2021-03-07 03:30:47
【问题描述】:

我正在尝试将会话存储在磁盘上以进行本地开发,但我遇到了应用程序希望我返回会话实例而不是对象的问题

function storeCallback(session) {
  console.log("storeCallback ", session);
  fs.writeFileSync("./session.json", JSON.stringify(session));
  return true;
}

function loadCallback(id) {
  console.log("loadCallback ", id);
  const session = fs.readFileSync("./session.json", "utf8");
  return JSON.parse(session);
}

会话如下所示:

Session {
   id: '0984e7db-ad80-4276-966d-9db54fac11c2',
   shop: 'swiftnextstep.myshopify.com',
   state: '113617456401679',
   isOnline: true
 }

保存并回读后,它看起来像这样

 {
   id: '0984e7db-ad80-4276-966d-9db54fac11c2',
   shop: 'swiftnextstep.myshopify.com',
   state: '113617456401679',
   isOnline: true
 }

我收到一个错误InternalServerError: Expected return to be instance of Session, but received instance of Object.

如何将我正在解析的对象从存储转换/转换为预期的 Session 类型?

【问题讨论】:

  • session 到底是什么?你能显示传递给storeCallback 的对象是在哪里创建的吗?
  • 你试过了吗....(storage as any) as Session?
  • @Sciffany 这不是 TypeScript
  • 你是对的,@CertainPerformance
  • @CertainPerformance,我无权访问调用 storeCallback 的代码,我只是从包中覆盖回调函数,Session 是 loadCallback 对其断言的实例类型

标签: javascript node.js shopify javascript-objects


【解决方案1】:

会话看起来只能从session.ts 导出。构造函数是空的,所以你不必担心,它只是一个具有属性的对象。要将非 Session 转换为 Session,您应该能够只分配给 Session 的属性。

import { Session } from "@shopify/shopify-api/dist/auth/session/session";

function loadCallback(id) {
  console.log("loadCallback ", id);
  return Object.assign(
    new Session(),
    JSON.parse(fs.readFileSync("./session.json", "utf8")))
  );
}

【讨论】:

  • 谢谢!现在可以了,我只是调整您的响应以匹配会话的正确位置。
【解决方案2】:

JSON 不保存类,所以当你阅读 JSON 时得到的只是一个带有属性的普通对象。通常,您将其重组为一个类的方式是为您的类创建一个构造函数,该构造函数接受您从 JSON 解析的确切对象作为构造函数的参数,然后构造函数将该数据复制到实例数据中你的班。或者,如果您不控制构造函数,那么您可以使用任何构造函数,创建该类型的新对象,然后从您从 JSON 解析的对象中设置您需要设置的属性。

可以直接在对象上设置原型,使用Object.setPrototypeOf() 解析 JSON,但我更喜欢使用构造函数设计,因为如果您在较新版本的代码中有其他属性或更新属性,那构造函数可以用适当的默认值以编程方式处理任何缺失的属性。在您的 JSON 中存储版本号通常也很有用,因此如果您随着时间的推移更改格式,您可以知道您正在从磁盘读取哪个版本,并且可以拥有适应旧版或新版 JSON 的代码。

注意,我通常也不直接JSON.stringify() 我的班级,因为我可能有不真正属于 JSON 的状态变量。相反,我创建了一个 .toJSON() 方法并让它为我生成 JSON,然后我的代码可以从我的实例数据中准确控制 JSON 中的内容。

【讨论】:

    【解决方案3】:

    JavaScript 对于object 值实际上没有主格类型。它确实有被具体化的原型(通过Object.getPrototypeOfConstructor.prototype)以及instanceof。看起来 Shopify 的库正在使用 instanceofgetProtoypeOf 来确定您的参数参数是否为“Session”。

    现在,我不熟悉 Shopify 的库,但您可以使用 Session 构造函数 - 或创建对象的克隆(继承原型)。试试这个:

    function loadCallback(id) {
      console.log("loadCallback ", id);
      const sessionJson = fs.readFileSync("./session.json", "utf8");
      const sessionObj  = new Session(); // assuming the ctor has no parameters
      
      const session2 = Object.assign( sessionObj, sessionJson ); // copy `sessionJson`'s properties into `sessionObj`.
    
      return session2;
    }
    

    【讨论】:

      猜你喜欢
      • 2016-02-20
      • 2012-08-02
      • 2016-04-14
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多