Skip to content

Commit

Permalink
Add missing generics in definitions
Browse files Browse the repository at this point in the history
  • Loading branch information
mike-marcacci committed Aug 12, 2024
1 parent 8e9813f commit b746b9b
Show file tree
Hide file tree
Showing 3 changed files with 842 additions and 280 deletions.
63 changes: 63 additions & 0 deletions src/type/__tests__/types-args.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,63 @@
/* eslint-disable */

import {
GraphQLBoolean,
GraphQLObjectType,
GraphQLString,
type GraphQLFieldConfig,
} from '../../index.js';

type Source = { id: string };
type Context = { user: { id: string } };
type Args = { foo: string };
type Fields = { hello: boolean };

// Should succeed while inferring all parameters.
new GraphQLObjectType<Source, Context, Fields>({
name: 'Query',
fields: {
hello: {
type: GraphQLBoolean,
args: {
foo: { type: GraphQLString },
},
resolve(_source, _args: { foo: string }) {
return true;
},
} as GraphQLFieldConfig<{}, {}, { foo: string }, boolean, 'hello'>,
},
});

// Should fail due to mismatching argument types.
new GraphQLObjectType<Source, Context, Fields>({
name: 'Query',
fields: {
// @ts-expect-error
hello: {
type: GraphQLBoolean,
args: {
foo: { type: GraphQLString },
},
resolve(_source, _args: { foo: number }) {
return true;
},
} as GraphQLFieldConfig<Source, Context, { foo: string }, boolean, 'hello'>,
},
});

// Should fail due to mismatching inferred argument types.
new GraphQLObjectType<Source, Context, Fields>({
name: 'Query',
fields: {
hello: {
type: GraphQLBoolean,
args: {
foo: { type: GraphQLString },
},
// @ts-expect-error
resolve(_source, _args: { foo: number }) {
return true;
},
},
},
});
228 changes: 228 additions & 0 deletions src/type/__tests__/types-objects.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,228 @@
/* eslint-disable */

import {
GraphQLBoolean,
GraphQLFloat,
GraphQLInterfaceType,
GraphQLNonNull,
GraphQLObjectType,
GraphQLString,
} from '../../index.js';

// Should succeed while inferring all parameters.
new GraphQLObjectType({
name: 'Query',
fields: {
hello: {
type: GraphQLBoolean,
resolve() {
return true;
},
},
},
});

// Should fail due to a mismatching inferred resolver type.
new GraphQLObjectType({
name: 'Query',
fields: {
hello: {
type: GraphQLBoolean,
// @ts-expect-error
resolve() {
return 'world';
},
},
},
});

// Should succeed with nullable inferred resolver type.
new GraphQLObjectType({
name: 'Query',
fields: {
hello: {
type: GraphQLBoolean,
resolve() {
return null;
},
},
},
});

// Should fail due to mismatched inferred nullability.
new GraphQLObjectType({
name: 'Query',
fields: {
hello: {
type: new GraphQLNonNull(GraphQLBoolean),
// @ts-expect-error
resolve() {
return null;
},
},
},
});

// Should succeed with explicit types and a resolver.
new GraphQLObjectType<{}, {}, { hello: boolean }>({
name: 'Query',
fields: {
hello: {
type: GraphQLBoolean,
resolve() {
return true;
},
},
},
});

// Should succeed with explicit types and no resolver when source supplies a
// sufficient value.
new GraphQLObjectType<{ hello: boolean }, {}, { hello: boolean }>({
name: 'Query',
fields: {
hello: {
type: GraphQLBoolean,
},
},
});

// Should fail with explicit types and a resolver that returns the wrong type.
new GraphQLObjectType<{}, {}, { hello: boolean }>({
name: 'Query',
fields: {
hello: {
// @ts-expect-error
type: GraphQLString,
// @ts-expect-error
resolve() {
return 1;
},
},
},
});

// Should fail with explicit types and a missing resolver when source does not
// supply a sufficient value.
new GraphQLObjectType<{}, {}, { hello: boolean }>({
name: 'Query',
fields: {
// @ts-expect-error
hello: {
type: GraphQLBoolean,
},
},
});

// Should fail with explicit types and no resolver when source returns the wrong
// type.
new GraphQLObjectType<{ hello: string }, {}, { hello: boolean }>({
name: 'Query',
fields: {
// @ts-expect-error
hello: {
type: GraphQLBoolean,
},
},
});

// Should fail with explicit types where a required field is not defined.
new GraphQLObjectType<{ hello: string }, {}, { hello: string }>({
name: 'Query',
// @ts-expect-error
fields: {},
});

// Should fail with explicit types when an extra field is defined.
new GraphQLObjectType<{}, {}, {}>({
name: 'Query',
fields: {
// TODO: Once TS supports the ability to infer from the type of a property,
// this should error. See:
// https://github.com/microsoft/TypeScript/issues/26242
// https://github.com/microsoft/TypeScript/pull/26349
// https://github.com/microsoft/TypeScript/issues/32794
// https://github.com/microsoft/TypeScript/issues/42388
// https://gist.github.com/shicks/219a081b74df7ad28e683761f51102f1
helloooo: {
type: GraphQLString,
},
},
});

type PersonSource = { name: string };
const GraphQLPerson = new GraphQLObjectType<PersonSource, {}, { name: string }>(
{
name: 'Person',
fields: {
name: {
type: GraphQLString,
},
},
},
);

// Should succeed returning the source type for a complex object field.
new GraphQLObjectType<{}, {}, { person: PersonSource }>({
name: 'Query',
fields: {
person: {
type: GraphQLPerson,
resolve(): PersonSource {
return { name: 'Somebody' };
},
},
},
});

// Should fail when returning an incorrect source type for a complex object
// field.
new GraphQLObjectType<{}, {}, { person: PersonSource }>({
name: 'Query',
fields: {
person: {
type: GraphQLPerson,
// @ts-expect-error
resolve(): string {
return 'Somebody';
},
},
},
});

// TODO: test with interfaces

const GraphQLTransaction = new GraphQLInterfaceType<
{ id: string; amount: number },
{},
{ id: string; amount: number }
>({
name: 'Transaction',
fields: {
id: { type: GraphQLString },
amount: { type: GraphQLFloat },
},
});

new GraphQLObjectType<{}, {}, { transaction?: { id: string; amount: number } }>(
{
name: 'Query',
fields: {
transaction: {
type: GraphQLTransaction,
resolve() {
return {
id: '1',
amount: 2.3,
};
},
},
},
},
);

// TODO: test with unions

// TODO: test with enums

// TODO: test with NonNull
Loading

0 comments on commit b746b9b

Please sign in to comment.