logologo
文档仓库
文档仓库
logologo
开始

概述

第一步
控制器
提供者
模块
中间件
异常过滤器
管道
守卫
拦截器
自定义装饰器

基础

自定义提供程序
异步提供者
动态模块
注入作用域
循环依赖
模块引用
懒加载模块
执行上下文
生命周期事件
发现服务
平台无关
单元测试

技术

配置
SQL
Mongo
验证
缓存
序列化
版本控制
任务调度
队列
日志
Cookies
事件
压缩
文件上传
文件流
HTTP 模块
Session
MVC
性能(Fastify)
SSE

安全

认证
授权
加密与哈希
Helmet
CORS
CSRF
速率限制

GraphQL

快速开始
解析器
变更
订阅
标量
指令
接口
联合与枚举
字段中间件
类型映射
插件
复杂度
扩展
CLI 插件
生成SDL
共享模型
其他功能
联邦

WebSocket

网关
异常过滤器
管道
守卫
拦截器
适配器

微服务

基础
Redis
MQTT
NATS
RabbitMQ
Kafka
gRPC
自定义传输
异常过滤器
管道
守卫
拦截器
部署
独立应用程序

CLI

概述
工作区
库
用法
脚本

OpenAPI

介绍
装饰器
类型映射
操作
其他特性
安全
类型与参数
CLI 插件

实用示例

REPL
CRUD生成器
SWC
Passport(认证)
热重载
MikroORM
TypeORM
Mongoose
Sequelize
路由模块
Swagger
健康检查
CQRS
Compodoc
Prisma
Sentry
静态资源
Commander
异步本地存储
Necord
套件(原Automock)

常见问题

Serverless
HTTP 适配器
长连接
全局前缀
原始请求体
混合应用
HTTPS & 多服务器
请求生命周期
错误

开发工具

概述
CI/CD
迁移指南
API参考(官方)

生态与案例

谁在用
精彩资源

支持

支持

社区

贡献者

最后更新于: 2025/11/18 02:11:37

上一页接口
下一页字段中间件

#联合类型

联合类型与接口非常相似,但它们不能指定类型之间的任何公共字段(了解更多此处 )。联合类型适用于从单个字段返回不相交的数据类型。

#代码优先

要定义 GraphQL 联合类型,我们必须定义组成该联合的类。根据 Apollo 文档中的示例 ,我们将创建两个类。首先是 Book:

import { Field, ObjectType } from '@nestjs/graphql';

@ObjectType()
export class Book {
  @Field()
  title: string;
}

然后是 Author:

import { Field, ObjectType } from '@nestjs/graphql';

@ObjectType()
export class Author {
  @Field()
  name: string;
}

完成这些设置后,使用从 @nestjs/graphql 包导出的 createUnionType 函数注册 ResultUnion 联合类型:

export const ResultUnion = createUnionType({
  name: 'ResultUnion',
  types: () => [Author, Book] as const,
});
警告

必须为 createUnionType 函数的 types 属性返回的数组添加 const 断言。如果未添加 const 断言,编译时将生成错误的声明文件,在其他项目中使用时会导致错误。

现在,我们可以在查询中引用 ResultUnion:

@Query(() => [ResultUnion])
search(): Array<typeof ResultUnion> {
  return [new Author(), new Book()];
}

这将生成以下 GraphQL 模式定义语言(SDL)部分:

type Author {
  name: String!
}

type Book {
  title: String!
}

union ResultUnion = Author | Book

type Query {
  search: [ResultUnion!]!
}

该库生成的默认 resolveType() 函数会根据解析器方法返回的值提取类型。这意味着必须返回类实例而非字面量 JavaScript 对象。

要提供自定义的 resolveType() 函数,请将 resolveType 属性传递给传入 createUnionType() 函数的 options 对象,如下所示:

export const ResultUnion = createUnionType({
  name: 'ResultUnion',
  types: () => [Author, Book] as const,
  resolveType(value) {
    if (value.name) {
      return Author;
    }
    if (value.title) {
      return Book;
    }
    return null;
  },
});

#模式优先

在模式优先方法中定义联合类型,只需使用 SDL 创建一个 GraphQL 联合类型。

type Author {
  name: String!
}

type Book {
  title: String!
}

union ResultUnion = Author | Book

然后,你可以使用类型生成功能(如快速开始章节所示)来生成对应的 TypeScript 定义:

export class Author {
  name: string;
}

export class Book {
  title: string;
}

export type ResultUnion = Author | Book;

联合类型需要在解析器映射中添加额外的 __resolveType 字段来确定应解析为哪种类型。另外请注意,ResultUnionResolver 类必须注册为任何模块的提供者。让我们创建一个 ResultUnionResolver 类并定义 __resolveType 方法。

@Resolver('ResultUnion')
export class ResultUnionResolver {
  @ResolveField()
  __resolveType(value) {
    if (value.name) {
      return 'Author';
    }
    if (value.title) {
      return 'Book';
    }
    return null;
  }
}
提示

所有装饰器均从 @nestjs/graphql 包中导出。

#枚举

枚举类型是一种特殊的标量类型,其值被限制在特定的允许值集合内(了解更多此处 )。这使您可以:

  • 验证该类型的任何参数是否为允许值之一
  • 通过类型系统表明某个字段永远是一组有限值中的一个

#代码优先

当使用代码优先方法时,您只需创建一个 TypeScript 枚举即可定义 GraphQL 枚举类型。

export enum AllowedColor {
  RED,
  GREEN,
  BLUE,
}

完成这些设置后,使用从 @nestjs/graphql 包导出的 registerEnumType 函数注册 AllowedColor 枚举:

registerEnumType(AllowedColor, {
  name: 'AllowedColor',
});

现在你可以在我们的类型中引用 AllowedColor 枚举:

@Field(type => AllowedColor)
favoriteColor: AllowedColor;

这将生成以下 GraphQL 模式定义语言(SDL)部分:

enum AllowedColor {
  RED
  GREEN
  BLUE
}

要为枚举提供描述,请将 description 属性传入 registerEnumType() 函数。

registerEnumType(AllowedColor, {
  name: 'AllowedColor',
  description: 'The supported colors.',
});

要为枚举值提供描述,或将某个值标记为弃用,请传入 valuesMap 属性,如下所示:

registerEnumType(AllowedColor, {
  name: 'AllowedColor',
  description: 'The supported colors.',
  valuesMap: {
    RED: {
      description: 'The default color.',
    },
    BLUE: {
      deprecationReason: 'Too blue.',
    },
  },
});

这将生成以下 SDL 格式的 GraphQL 模式:

"""
The supported colors.
"""
enum AllowedColor {
  """
  The default color.
  """
  RED
  GREEN
  BLUE @deprecated(reason: "Too blue.")
}

#模式优先

在模式优先的方法中定义枚举器,只需用 SDL 创建一个 GraphQL 枚举即可。

enum AllowedColor {
  RED
  GREEN
  BLUE
}

然后您可以使用类型生成功能(如快速入门章节所示)来生成对应的 TypeScript 定义:

export enum AllowedColor {
  RED
  GREEN
  BLUE
}

有时后端会强制要求枚举在内部使用与公开 API 不同的值。在这个例子中,API 包含 RED,但在解析器中我们可能使用 #f00 代替(了解更多此处 )。要实现这一点,需要为 AllowedColor 枚举声明一个解析器对象:

export const allowedColorResolver: Record<keyof typeof AllowedColor, any> = {
  RED: '#f00',
};
提示

所有装饰器均从 @nestjs/graphql 包中导出。

然后将此解析器对象与 GraphQLModule#forRoot() 方法的 resolvers 属性一起使用,如下所示:

GraphQLModule.forRoot({
  resolvers: {
    AllowedColor: allowedColorResolver,
  },
});