website/src/pages/plugins/typescript/typescript-resolvers.mdx
import { Callout } from '@theguild/components' import { PluginApiDocs, PluginHeader } from '@/components/plugin' import { pluginGetStaticProps } from '@/lib/plugin-get-static-props' export const getStaticProps = pluginGetStaticProps(__filename, { hasOperationsNote: true })
<Callout> This plugin is meant to be used for low-level use cases or as building block for presets.For building a GraphQL server schema we recommend using the server-preset.
</Callout>
You can find a blog post we wrote about using and customizing this plugin here
</Callout>Run graphql-codegen as usual, with this new plugin:
import type { CodegenConfig } from '@graphql-codegen/cli'
const config: CodegenConfig = {
schema: 'schema.json',
generates: {
'./src/resolvers-types.ts': {
plugins: ['typescript', 'typescript-resolvers']
}
}
}
export default config
Import the types from the generated file and use in the resolver:
import { Resolvers } from './resolvers-types'
export const resolvers: Resolvers = {
Query: {
myQuery: (root, args, context) => {}
}
}
This will make the resolver fully typed and compatible with typescript compiler, including the handler's arguments and return value.
Generated resolvers can be passed directly into graphql-tools makeExecutableSchema function.
By default apollo-server will not work with generated resolvers signature.
If you are using Apollo Server with TypeScript, note that you need to set useIndexSignature: true in your config, in order to add a compatible index signature (more info).
import type { CodegenConfig } from '@graphql-codegen/cli'
const config: CodegenConfig = {
generates: {
'./resolvers-types.ts': {
config: {
useIndexSignature: true
},
plugins: ['typescript', 'typescript-resolvers']
}
}
}
export default config
If you wish to have an easy start, and have the ability to use resolvers chaining without models types, you can also add to your config defaultMapper: Partial<{T}>. This will allow you to return partial types in your resolvers.
mappers)If you wish to use your custom model types, codegen allow you to use mappers feature to map GraphQL types to your custom model types. You can find an article explaining how to use mappers here.
Here's the basic example of using it:
import type { CodegenConfig } from '@graphql-codegen/cli'
const config: CodegenConfig = {
schema: 'schema.graphql',
generates: {
'./resolvers-types.ts': {
config: {
contextType: 'models#MyContextType',
mappers: {
User: './models#UserModel',
Profile: './models#UserProfile'
}
},
plugins: ['typescript', 'typescript-resolvers']
}
}
}
export default config
Apollo-Server and schemas built with graphql-tools supports creating resolvers for GraphQL enums.
This is helpful because you can have internal values that are different from the public enum values, and you can use the internal values in your resolvers.
Codegen allows you to specify either mappers or enumValues to map enums in your resolvers, and if you are using it for enums, you'll get a resolver signature for the enum resolvers as well.
With the following schema:
type Query {
favoriteColor: Color!
}
enum Color {
RED
BLUE
}
import type { CodegenConfig } from '@graphql-codegen/cli'
const config: CodegenConfig = {
schema: 'schema.graphql',
generates: {
'./resolvers-types.ts': {
config: {
enumValues: {
Color: './enums#ColorsCode'
}
},
plugins: ['typescript', 'typescript-resolvers']
}
}
}
export default config
export enum ColorsCode {
MY_RED = '#FF0000',
MY_BLUE = '#0000FF'
}
import { Resolvers } from './resolvers-types'
import { ColorsCode } from './enums'
const resolvers: Resolvers = {
Color: {
RED: ColorsCode.MY_RED,
BLUE: ColorsCode.MY_BLUE
},
Query: {
favoriteColor: () => ColorsCode.MY_RED // Now you cn return this, and it will be mapped to your actual GraphQL enum
}
}
You can also define the same with explicit enum values:
import type { CodegenConfig } from '@graphql-codegen/cli'
const config: CodegenConfig = {
schema: 'schema.graphql',
generates: {
'./resolvers-types.ts': {
config: {
enumValues: {
Color: {
RED: '#FF0000',
BLUE: '#0000FF'
}
}
},
plugins: ['typescript', 'typescript-resolvers']
}
}
}
export default config
Or, with mappers:
import type { CodegenConfig } from '@graphql-codegen/cli'
const config: CodegenConfig = {
schema: 'schema.graphql',
generates: {
'./resolvers-types.ts': {
config: {
mappers: {
Color: './enums#ColorsCode'
}
},
plugins: ['typescript', 'typescript-resolvers']
}
}
}
export default config
In some case, you might want to share some common mappers between many output file configurations.
To do so, you can leverage the YAML references features as follow:
import type { CodegenConfig } from '@graphql-codegen/cli'
const sharedMappers = {
ID: 'IDType'
}
const config: CodegenConfig = {
schema: 'schema.graphql',
documents: 'src/*.ts',
generates: {
'resolvers-types-1.ts': {
plugins: ['typescript', 'typescript-resolvers'],
config: {
mappers: {
...sharedMappers,
String: 'StringType'
}
}
},
'resolvers-types-2.ts': {
plugins: ['typescript', 'typescript-resolvers'],
config: {
mappers: {
...sharedMappers,
String: 'StringType'
}
}
}
}
}
export default config
The above configuration will provide the ID type mapping to both resolvers-types-1.ts and resolvers-types-2.ts files.
The complete example is available here: codegen-repros/reusable-mappers
You can also achieve a similar reusable mappers configuration by providing a TypeScript or JavaScript file configuration.