Skip to content

Commit

Permalink
[fix] Prevent resolver from widening output type (#74)
Browse files Browse the repository at this point in the history
If the resolver for a field returns a union where one of the constituents
satisfies the expected type, then TypeScript widens the `Out` type to allow the
union, but the resolver's type should be limited to what the `type` option
allows. Added `NoInfer` utility prevents TypeScript from widening the
type in this case.
  • Loading branch information
andrew0 authored Dec 8, 2023
1 parent cd9c5f9 commit 4e327db
Show file tree
Hide file tree
Showing 2 changed files with 26 additions and 2 deletions.
6 changes: 4 additions & 2 deletions src/define.ts
Original file line number Diff line number Diff line change
Expand Up @@ -31,13 +31,15 @@ type ExtensionsMap = {
};
};

type NoInfer<T> = [T][T extends any ? 0 : never];

type ResolvePartialMandatory<Src, Arg, Out> = {
resolve: (
src: Src,
args: TOfArgMap<ArgMap<Arg>>,
ctx: GqlContext,
info: graphql.GraphQLResolveInfo
) => PromiseOrValue<Out>;
) => PromiseOrValue<NoInfer<Out>>;
};

type ResolvePartialOptional<Src, Arg, Out> = {
Expand All @@ -46,7 +48,7 @@ type ResolvePartialOptional<Src, Arg, Out> = {
args: TOfArgMap<ArgMap<Arg>>,
ctx: GqlContext,
info: graphql.GraphQLResolveInfo
) => PromiseOrValue<Out>;
) => PromiseOrValue<NoInfer<Out>>;
};

function builtInScalar<Src>(
Expand Down
22 changes: 22 additions & 0 deletions test-api/api.ts
Original file line number Diff line number Diff line change
Expand Up @@ -234,3 +234,25 @@ declare module '../src/types.js' {
fields: () => [],
});
}

{
type Foo = { foo: string };
type Bar = { bar: string };

const FooType = Gql.Object<Foo>({
name: 'Foo',
fields: () => [
Gql.Field({
name: 'foo',
type: Gql.NonNull(Gql.String),
}),
],
});

Gql.Field({
name: 'getFoo',
type: Gql.NonNull(FooType),
// @ts-expect-error: Type 'Foo | Bar' is not assignable to type 'PromiseOrValue<Foo>'.
resolve: () => ({ bar: 'bar' } as Foo | Bar),
});
}

1 comment on commit 4e327db

@github-actions
Copy link

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

The changes have been published to npm.

yarn add -E [email protected]

Please sign in to comment.