79-Nodejs课程2023:资源:递归资源
#typescript #node #mongodb #fastify

在本文中,我们将查看如何将资源用作输出类型以及如何实现。

目的

为什么我们需要分配给resource类型的输出密钥?好吧,因为我们使用的是mongodb,这意味着可以将文档存储在另一个文档中的单个键中,例如,我们可以将createdBy对象存储在任何文档中(我们以后会做),依此类推。

因此,我们需要映射该createdBy对象以使用其适当的资源来制作适当的响应输出。

我们将学习如何使用两件事,检查变量是否为类型类别,也是部分递归,这意味着可以自我调用的类/函数(以某种方式)。

实施之前

我们将在我们的Resource类中添加一个新功能,该功能允许输出为资源,这要求我们添加对valueType的支票以检查它是否是Resource类型,所以我想向您展示如何检查变量是否是类的类型(类本身而不是对象是其实例)。

// some-file.ts
class MyClass {

}

const A = MyClass;

// check if A is a `MyClass` type

if (A.prototype instanceof MyClass) {
  // A is a MyClass type
}

我们在这里使用prototype检查该类是否是另一类的实例,因此我们可以使用它来检查valueType是否是Resource类型。

因此,我们可以说如果要检查变量是否为class类型,我们使用prototype,如果要检查变量是否是类的对象/实例,我们直接使用instanceof

执行

现在让我们看看如何做到这一点。

这很简单,我们只是分配给输出密钥,假设createdBy UserResource类型的值,在我们的toJSON中,我们将添加另一个检查,如果给定值类型为type a Resource,那么我们将传递数据对此,否则我们将完全跳过密钥。

// src/core/resources/resource.ts
import { get } from "@mongez/reinforcements";

// this will be used to skip the output property if it is missing from the given resource
const missingKey = Symbol("missing");

export default class Resource {
  /**
   * Constructor
   */
  public constructor(protected resource: any = {}) {
    //
  }

  /**
   * Output shape
   */
  protected output: any = {};

  /**
   * {@inheritDoc}
   */
  public toJSON() {
    // final output
    const data: Record<string, any> = {};

    // loop through the output property
    for (const key in this.output) {
      // get the value type
      const valueType = this.output[key];
      // get the value, and also make sure to skip the output property if it is missing from the given resource
      let value = get(this.resource, key, missingKey);

      // skip the output property if it is missing from the given resource
      if (value === missingKey) {
        continue;
      }

      if (typeof valueType === "string") {
        // cast the value
        value = this.cast(value, valueType);
      } else if (valueType.prototype instanceOf Resource) {
        // if the value type is a resource, then pass the value to it
        value = new valueType(value).toJSON();
      } else if (typeof valueType === "function") {
        // call the custom output handler
        value = valueType(value);
      }

      // just for now sett the output value to the data
      data[key] = value;
    }

    return data;
  }

  /**
   * Builtin casts
   */
  protected cast(value: any, type: string) {
    switch (type) {
      case "number":
        return Number(value);
      case "float":
      case "double":
        return parseFloat(value);
      case "int":
      case "integer":
        return parseInt(value);
      case "string":
        return String(value);
      case "boolean":
        return Boolean(value);
      default:
        return value;
    }
  }
}

在这里,我们只是添加了一些if语句,该语句正在检查值类型是否为Resource类型,如果是的,则我们将其传递给它,否则我们将完全跳过密钥。

现在我们可以更新我们的UserResource

// src/app/users/resources/user-resource.ts
import Resource from 'core/resources/resource';
import { uploadsUrl } from 'core/utils/urls';

export default class UserResource extends Resource {
  /**
   * Output shape
   */
  protected output: any = {
    id: 'number',
    name: 'string',
    email: 'string',
    age: 'number',
    avatar: uploadsUrl,
    createdBy: UserResource,
 };
}

这应该可以与您合作,将数据传递给名为createdBy的键并传递给对象。

这里的重点是使用UserResource类映射该数据为正确的输出。

这也称为Recursive Resource,因为我们使用相同的资源将数据映射到输出。

- 结论

我们刚刚学会了如何实现彼此内部资源的递归呼吁,以及如何检查变量是否为类。

â•给我买一杯咖啡。

如果您喜欢我的文章并看到对您有用,则可以buy me a coffee,它将帮助我继续前进并继续创建更多内容。

ð项目存储库

您可以在Github

上找到此项目的最新更新

ð加入我们的社区

加入Discord上的社区以获得帮助和支持(节点JS 2023频道)。

ð视频课程(阿拉伯语)

如果您想以视频格式学习此课程,则可以在Youtube上找到该课程,该课程是阿拉伯语。

ð奖励内容ð

您可能会看这些文章,这肯定会提高您的知识和生产力。

一般主题

软件包和库

React JS软件包

课程(文章)