Skip to main content

Fix coercion table for list

At a glance

Timeline


The spec claims:

Expected TypeProvided ValueCoerced Value
[Int][1, 2, 3][1, 2, 3]
[Int]1[1]
[[Int]][1, 2, 3]Error: Incorrect item value

but this isn't correct. This final line should actually be:

Expected TypeProvided ValueCoerced Value
[[Int]][1, 2, 3][[1], [2], [3]]
This is the behavior GraphQL.js has already.

Reproduction:

import { GraphQLInt, GraphQLList, GraphQLNonNull, GraphQLObjectType, GraphQLSchema, GraphQLString, graphqlSync, printSchema, validateSchema } from "graphql";

const Query = new GraphQLObjectType({
name: "Query",
fields: {
field: {
args: {
arg: {
type: new GraphQLList(new GraphQLList(GraphQLInt)),
},
},
type: new GraphQLNonNull(GraphQLString),
resolve(_, { arg }) {
return JSON.stringify(arg);
},
},
},
});
const schema = new GraphQLSchema({
query: Query,
});

const result = graphqlSync({
schema,
source: /* GraphQL */ `
query {
field(arg: [1, 2, 3])
}
`,
variables: {},
});
const errors = validateSchema(schema);
if (errors.length) {
console.dir(errors);
process.exit(1);
}
console.log(printSchema(schema));
console.log(JSON.stringify(result, null, 2));

And it follows from the spec text:

When expected as an input, list values are accepted only when each item in the list can be accepted by the list’s item type.

If the value passed as an input to a list type is not a list and not the null value, then the result of input coercion is a list of size one, where the single item value is the result of input coercion for the list’s item type on the provided value (note this may apply recursively for nested lists).


I've fixed this, and added another couple of examples.

I will be following up with a separate PR that fixes another issue in list type coercion; but this should be an easy merge.