Scalars¶
A GraphQL object type has a name and fields, but at some point those fields have to resolve to some concrete data. That's where the scalar types come in: they represent the leaves of the query (read more here). GraphQL includes the following default types: Int, Float, String, Boolean and ID. In addition to these built-in types, you may need to support custom atomic data types (e.g., Date).
Code first¶
The code-first approach ships with five scalars in which three of them are simple aliases for the existing GraphQL types.
ID(alias forGraphQLID) - represents a unique identifier, often used to refetch an object or as the key for a cacheInt(alias forGraphQLInt) - a signed 32‐bit integerFloat(alias forGraphQLFloat) - a signed double-precision floating-point valueGraphQLISODateTime- a date-time string at UTC (used by default to representDatetype)GraphQLTimestamp- a signed integer which represents date and time as number of milliseconds from start of UNIX epoch
The GraphQLISODateTime (e.g. 2019-12-03T09:54:33Z) is used by default to represent the Date type. To use the GraphQLTimestamp instead, set the dateScalarMode of the buildSchemaOptions object to 'timestamp' as follows:
Likewise, the GraphQLFloat is used by default to represent the number type. To use the GraphQLInt instead, set the numberScalarMode of the buildSchemaOptions object to 'integer' as follows:
In addition, you can create custom scalars. For example, to create a Date scalar, simply create a new class.
With this in place, register DateScalar as a provider.
Now we can use the Date type in our classes.
Schema first¶
To define a custom scalar (read more about scalars here), create a type definition and a dedicated resolver. Here (as in the official documentation), we’ll use the graphql-type-json package for demonstration purposes. This npm package defines a JSON GraphQL scalar type.
Start by installing the package:
Once the package is installed, we pass a custom resolver to the forRoot() method:
Now we can use the JSON scalar in our type definitions:
Another method to define a scalar type is to create a simple class. Assume we want to enhance our schema with the Date type.
With this in place, register DateScalar as a provider.
Now we can use the Date scalar in type definitions.
By default, the generated TypeScript definition for all scalars is any - which isn't particularly typesafe.
But, you can configure how Nest generates typings for your custom scalars when you specify how to generate types:
Hint
Alternatively, you can use a type reference instead, for example: DateTime: Date. In this case, GraphQLDefinitionsFactory will extract the name property of the specified type (Date.name) to generate TS definitions. Note: adding an import statement for non-built-in types (custom types) is required.
Now, given the following GraphQL custom scalar types:
We will now see the following generated TypeScript definitions in src/graphql.ts:
Here, we've used the customScalarTypeMapping property to supply a map of the types we wish to declare for our custom scalars. We've
also provided an additionalHeader property so that we can add any imports required for these type definitions. Lastly, we've added
a defaultScalarType of 'unknown', so that any custom scalars not specified in customScalarTypeMapping will be aliased to
unknown instead of any (which TypeScript recommends using since 3.0 for added type safety).
Hint
Note that we've imported _BigNumber from bignumber.js; this is to avoid circular type references.