You must create a custom scalar (BigNumber.ts):
import { Kind, GraphQLError, GraphQLScalarType } from "graphql";
import { BigNumber } from "ethers";
export const GraphQLBigNumber: GraphQLScalarType = new GraphQLScalarType({
name: "BigNumber",
description:
"A field whose value is a valid BigNumber which safely allows mathematical operations on numbers of any magnitude",
serialize(value) {
if (value === null) return value;
else return BigNumber.from(value.toString()).toString();
},
parseValue(value) {
if (value === null) return value;
else return BigNumber.from(value.toString());
},
parseLiteral(ast) {
if (ast.kind !== Kind.STRING && ast.kind !== Kind.Int) {
throw new GraphQLError(
`Can only validate strings or ints as BigNumbers but got a: ${ast.kind}`
);
}
if (ast.value === null) return ast.value;
else return BigNumber.from(value.toString());
},
extensions: {
codegenScalarType: "BigNumber | string | number",
},
});
Then you can just use it in your field decorator:
// ...
import { GraphQLBigNumber } from "./BigNumber";
@ObjectType()
@Entity()
export class Transfer extends BaseEntity {
@Field(() => GraphQLBigNumber) // Here!
@Column({
type: "numeric",
precision: 78,
scale: 0,
transformer: new BigNumberTransformer(),
})
amount!: BigNumber;
}
Optionally, you can declare the association between the reflected property type and your scalar to automatically map it (no need for explicit type annotation!):
@ObjectType()
@Entity()
export class Transfer extends BaseEntity {
@Field() // Magic goes here - no type annotation!
@Column({
type: "numeric",
precision: 78,
scale: 0,
transformer: new BigNumberTransformer(),
})
amount!: BigNumber;
}
All you need to do is register the association map in the buildSchema options:
import { buildSchema } from "type-graphql";
import { BigNumber } from "ethers";
import { GraphQLBigNumber } from "./BigNumber";
const schema = await buildSchema({
resolvers,
scalarsMap: [{ type: BigNumber, scalar: GraphQLBigNumber }],
});
However, you must be aware that this will only work when the TypeScript reflection mechanism can handle it. So your class property type must be a class, not an enum, union or interface.