# Unions and Enums

Source: https://docs.nestjs.com/graphql/unions-and-enums

Union types are similar to interfaces, but they don't specify any common fields between the types (see [union types](https://graphql.org/learn/schema/#union-types) in the GraphQL documentation). Unions are useful for returning disjoint data types from a single field.

#### Code first

To define a GraphQL union type, first define the classes that make up the union. Following the [union type example](https://www.apollographql.com/docs/apollo-server/schema/unions-interfaces/#union-type) from the Apollo documentation, we'll create two classes. First, `Book`:

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

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

And then `Author`:

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

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

With this in place, register the `ResultUnion` union using the `createUnionType` function exported from the `@nestjs/graphql` package:

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

> warning **Warning** Add a const assertion (`as const`) to the array returned by the `types` property of the `createUnionType` function. Without it, TypeScript generates an incorrect declaration file at compile time, and using the union from another project fails with an error.

Now you can reference `ResultUnion` in a query:

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

This generates the following part of the GraphQL schema in SDL:

```graphql
type Author {
  name: String!
}

type Book {
  title: String!
}

union ResultUnion = Author | Book

type Query {
  search: [ResultUnion!]!
}
```

The default `resolveType()` function generated by the library determines the type based on the value returned from the resolver method. This means that you must return class instances, not plain JavaScript object literals.

To provide a custom `resolveType()` function, pass the `resolveType` property in the options object of the `createUnionType()` function:

```typescript
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;
  },
});
```

#### Schema first

To define a union in the schema first approach, create a GraphQL union with SDL:

```graphql
type Author {
  name: String!
}

type Book {
  title: String!
}

union ResultUnion = Author | Book
```

Then, you can use the typings generation feature (as shown in the [GraphQL quick start](/graphql/quick-start) chapter) to generate the corresponding TypeScript definitions:

```typescript
export class Author {
  name: string;
}

export class Book {
  title: string;
}

export type ResultUnion = Author | Book;
```

Unions require an extra `__resolveType` field in the resolver map to determine which type the union resolves to. Create a `ResultUnionResolver` class and define the `__resolveType` method, which returns the name of the concrete type. Remember to register `ResultUnionResolver` as a provider in a module.

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

> info **Hint** All decorators are exported from the `@nestjs/graphql` package.

### Enums

Enumeration types are a special kind of scalar restricted to a particular set of allowed values (see [enumeration types](https://graphql.org/learn/schema/#enumeration-types) in the GraphQL documentation). They allow you to:

- validate that any arguments of this type are one of the allowed values
- communicate through the type system that a field will always be one of a finite set of values

#### Code first

In the code first approach, you define a GraphQL enum type by creating a TypeScript enum:

```typescript
export enum AllowedColor {
  RED,
  GREEN,
  BLUE,
}
```

With this in place, register the `AllowedColor` enum using the `registerEnumType` function exported from the `@nestjs/graphql` package:

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

Now you can reference `AllowedColor` in your types:

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

This generates the following part of the GraphQL schema in SDL:

```graphql
enum AllowedColor {
  RED
  GREEN
  BLUE
}
```

To provide a description for the enum, pass the `description` property to the `registerEnumType()` function:

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

To provide descriptions for the enum values, or to mark a value as deprecated, pass the `valuesMap` property:

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

This generates the following GraphQL schema in SDL:

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

#### Schema first

To define an enum in the schema first approach, create a GraphQL enum with SDL:

```graphql
enum AllowedColor {
  RED
  GREEN
  BLUE
}
```

Then you can use the typings generation feature (as shown in the [GraphQL quick start](/graphql/quick-start) chapter) to generate the corresponding TypeScript definitions:

```typescript
export enum AllowedColor {
  RED = "RED",
  GREEN = "GREEN",
  BLUE = "BLUE"
}
```

Sometimes a backend uses a different internal value for an enum than the one exposed in the public API. In this example, the API contains `RED`, but resolvers use `#f00` instead (see [internal values](https://www.apollographql.com/docs/apollo-server/schema/scalars-enums/#internal-values) in the Apollo documentation). To accomplish this, declare a resolver object for the `AllowedColor` enum:

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

> info **Hint** All decorators are exported from the `@nestjs/graphql` package.

Then pass this resolver object in the `resolvers` property of the `GraphQLModule#forRoot()` method:

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