Type-graphql: Custom scalar tuple causes the type in schema to be a list

Created on 26 May 2020  路  2Comments  路  Source: MichalLytek/type-graphql

Describe the Bug
I'm trying to create a custom scalar for a geojson position. A geojson position is a tuple of the form [longitute, latitude, eleveation?]. If I define the type (in Typescript) as such, when I use the scalar in an InputType, the type in the schema is always a list, regardless of the fact that I specify the field is not a list with @Field(() => Position).

So for example if I define an InputType Point,

type GeoJsonPosition = [number, number, elevation?]
const Position = new GraphQLScalarType(...)

@InputType()
export class Point {
  @Field(() => Position)
  coordinates: GeoJsonPosition
}

It appears in the schema as,

input Point {
  coordinates: [Position!]!
}

To Reproduce

  1. Define a new GraphQLScalar
  2. Define a type for the scalar as some tuple or array type, any[] or [...any]
  3. Use the scalar as a singular value (not as a list) in some InputType

Expected Behavior
The type in the schema should not be a list. I'd expect the schema to look like this,

input Point {
  coordinates: Position!
}

Environment (please complete the following information):

  • OS: MacOS Catalina 10.15.4
  • Node 12.16.3
  • Package version: 1.0.0-rc.2
  • TypeScript: 3.9.3, TS-Node 8.10.1

Additional Context
Here is a CodeSandbox that reproduces the problem: https://codesandbox.io/s/type-graphql-problem-lpof7

Bug Community Solved

All 2 comments

If I define the type (in Typescript) as such, when I use the scalar in an InputType, the type in the schema is always a list

That's the legacy behavior for explicit type in case of array, as TS cannot reflect string[], it's readed as Array.

So I allowed to pass the array item type, like:

@Field(() => String)
items: string[];

or

@Field(() => String, { isArray: true })
items: string[];

But then I switched to the array syntax, like @Field(() => [String]) and removed the isArray option but it's still infered from the TS type like in your case.

As a workaround, you can just write something like:

type TypeWorkaround<T> = T;

And then use it in your code:

@Field(() => Position)
coordinates: TypeWorkaround<GeoJsonPosition>;

I will try to remove the legacy reflection before the 1.0.0 release

Closing via b4afef4 馃敀

Was this page helpful?
0 / 5 - 0 ratings

Related issues

limenutt picture limenutt  路  3Comments

MichalLytek picture MichalLytek  路  4Comments

tafelito picture tafelito  路  3Comments

glentakahashi picture glentakahashi  路  3Comments

robertchung97 picture robertchung97  路  3Comments