跳到主要内容

映射类型

注意

本章仅适用于代码优先方式。

在构建 CRUD(创建/读取/更新/删除)等功能时,通常会构造基础实体类型的变体。 Nest 提供了几个实用函数,执行类型转换以使此任务更加方便。

Partial(部分)

在构建输入验证类型(也称为数据传输对象或 DTO)时,通常会构建相同类型的创建和更新变体。 例如,创建变体可能要求所有字段,而更新变体可能会使所有字段都是可选的。

Nest 提供了 PartialType() 实用函数,以使此任务更加轻松并减少样板代码。

PartialType() 函数返回一个类型(类),该类型中输入类型的所有属性均设置为可选。 例如,假设我们有一个如下所示的创建类型:

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

@Field()
password: string;

@Field()
firstName: string;
}

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

@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) {}

Pick(选择)

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 包导入的。

Omit(省略)

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 包导入的。

Intersection(交集)

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),
) {}