NestJS 9 GraphQL 中文文档(十) - 映射类型

331 阅读3分钟

Nest 最新的版本为V9,较之前的V7/8有不小改动,GraphQL 部分官方文档之前的V8也是本人翻译的,有很多不完善的地方,这次打算重新精细翻译一遍,会持续更新这块内容,并最后贡献给中文文档仓库,为中文社区贡献一份力量。有兴趣的小伙伴记得要关注收藏。

警告⚠️
此章节仅适用于代码优先方式。

当你构建CRUD(创建/读取/更新/删除)等功能时,在基本实体类型上构建变体通常很有用。Nest提供了几个实用函数来执行类型转换,使这项任务更加方便。

局部

当构建输入验证类型(也叫做数据传输对象或DTOs)时,在同一类型上构建createupdate变体通常会很有用。举个例子,create变体的所有字段可能都是必选的,但update变体的所有字段可能都是可选的。

Nest提供了PartialType() 实用函数来简化这项任务并且最大限度地减少模版文件。

PartialType() 函数返回一个类型(类),其中包含输入类型的所有属性,并都将其设置为可选。举个例子,假设我们有一个如下所示的create类型:

@InputType()
class CreateUserInput {
  @Field()
  email: string;

  @Field()
  password: string;

  @Field()
  firstName: string;
}

默认情况下,所有这些字段都是必选的。要使用相同但每个都可选的字段,创建另一个类型,使用PartialType() 把类引用作为参数传递即可:

@InputType()
export class UpdateUserInput extends PartialType(CreateUserInput) {}

提示
PartialType() 函数是从@nestjs/graphql 包导出的。

PartialType() 函数采用一个可选的第二参数,该参数是对装饰器工厂的引用。此参数可用于更改应用于结果(子)类的装饰器函数。如果没有特别说明,子类将有效地使用与类(第一个参数引用的类)相同的装饰器。在上面的示例中,我们扩展了用@InputType() 装饰器注释的CreateUserInput。因为我们希望UpdateUserInput也被视为用@InputType() 装饰过,所以我们不需要将InputType 作为第二个参数传递。如果父子类型不同,(例如:父类用@ObjectType装饰),那么我们就要传递InputType作为第二个参数。例如:

@InputType()
export class UpdateUserInput extends PartialType(User, InputType) {}

选取

PickType() 函数通过从输入类型中选取一组属性构造了一个新的类型(类)。例如,假设我们有一个如下的类型:

@InputType()
class CreateUserInput {
  @Field()
  email: string;

  @Field()
  password: string;

  @Field()
  firstName: string;
}

我们可以使用PickType() 实用函数从这个类中选取一组属性:

@InputType()
export class UpdateEmailInput extends PickType(CreateUserInput, [
  'email',
] as const) {}

提示
PickType() 函数是从@nestjs/graphql包里导出的。

忽略

OmitType() 函数从输入类型中选取所有属性然后删除一组特定的键来构造一个类型。例如,假设我们有一个如下的类型:

@InputType()
class CreateUserInput {
  @Field()
  email: string;

  @Field()
  password: string;

  @Field()
  firstName: string;
}

我们可以生成一个派生类型,它具有email之外的所有属性,如下所示。在这个构造中,OmitType的第二个参数是一个属性名数组。

@InputType()
export class UpdateUserInput extends OmitType(CreateUserInput, [
  'email',
] as const) {}

提示
OmitType() 函数是从@nestjs/graphql包里导出的。

并集

IntersectionType() 函数把两种类型合并为一个新的类型(类)。例如,假设我们有如下两个类型:

@InputType()
class CreateUserInput {
  @Field()
  email: string;

  @Field()
  password: string;
}

@ObjectType()
export class AdditionalUserInfo {
  @Field()
  firstName: string;

  @Field()
  lastName: string;
}

我们可以生成一个新类型,它合并了两个类型中的所有属性。

@InputType()
export class UpdateUserInput extends IntersectionType(
  CreateUserInput,
  AdditionalUserInfo,
) {}

提示
IntersectionType() 函数是从@nestjs/graphql包里导出的。

组合

这些映射实用函数都是可组合的。例如,以下代码将产生一个类型(类),它包含CreateUserInput 类型的中除了email的所有属性,并且这些属性都将被设置可选:

@InputType()
export class UpdateUserInput extends PartialType(
  OmitType(CreateUserInput, ['email'] as const),
) {}