Skip to content

Commit

Permalink
fix(document-builder): infer multiple field aliases (#1266)
Browse files Browse the repository at this point in the history
  • Loading branch information
jasonkuhrt authored Nov 18, 2024
1 parent 9ad7136 commit 9119f04
Show file tree
Hide file tree
Showing 5 changed files with 45 additions and 31 deletions.
34 changes: 18 additions & 16 deletions src/documentBuilder/InferResult/Alias.ts
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
import type { Tuple, ValuesOrEmptyObject } from '../../lib/prelude.js'
import type { Tuple, UnionMerge, ValuesOrEmptyObject } from '../../lib/prelude.js'
import type { Schema } from '../../types/Schema/__.js'
import type { Select } from '../Select/__.js'
import type { OutputField } from './OutputField.js'
Expand All @@ -9,21 +9,23 @@ export type Alias<
$Node extends Schema.OutputObject,
$SelectionSet,
> =
ValuesOrEmptyObject<
{
[
$Select in keyof $SelectionSet as $SelectionSet[$Select] extends Select.SelectAlias.SelectAlias
? $Select
: never
]:
InferSelectAlias<
// @ts-expect-error We know this satisfies the alias type constraint b/c of the key filtering above.
$SelectionSet[$Select],
$Select,
$Schema,
$Node
>
}
UnionMerge<
ValuesOrEmptyObject<
{
[
$Select in keyof $SelectionSet as $SelectionSet[$Select] extends Select.SelectAlias.SelectAlias
? $Select
: never
]:
InferSelectAlias<
// @ts-expect-error We know this satisfies the alias type constraint b/c of the key filtering above.
$SelectionSet[$Select],
$Select,
$Schema,
$Node
>
}
>
>

// dprint-ignore
Expand Down
8 changes: 4 additions & 4 deletions src/documentBuilder/InferResult/__.test-d.ts
Original file line number Diff line number Diff line change
Expand Up @@ -104,10 +104,10 @@ assertEqual<$<{objectWithArgs: ['x', { $: {id:''}; id:true }]}>, { x: { id: null
// one field multiple times
assertEqual<$<{ id: [['id1', true],['id2', true]] }>, { id1: null | string; id2: null | string }>()
// multiple fields
// assertEqual<
// $<{ id: [['id1', true],['id2', true]], abcEnum: ['abcEnum1', true] }>,
// { id1: null | string; id2: null | string; abcEnum1: null | db.ABCEnum }
// >()
assertEqual<
$<{ id: [['id1', true],['id2', true]], abcEnum: ['abcEnum1', true] }>,
{ id1: null | string; id2: null | string; abcEnum1: null | db.ABCEnum }
>()
// AssertEqual<RS<{ id_as: true }>, { id_as: InferResult.Errors.UnknownFieldName<'id_as', Schema.Root.Query> }>()
// AssertEqual<RS<{ id_as_$: true }>, { id_as_$: InferResult.Errors.UnknownFieldName<'id_as_$', Schema.Root.Query> }>()
// union fragment
Expand Down
6 changes: 3 additions & 3 deletions src/documentBuilder/requestMethods/document.test-d.ts
Original file line number Diff line number Diff line change
Expand Up @@ -21,7 +21,7 @@ test(`document with one query`, async () => {
type $Parameters = Parameters<typeof run>
expectTypeOf<$Parameters>().toEqualTypeOf<[]>()
const result = await run()
expectTypeOf(result).toEqualTypeOf<{ id: string | null }>()
expectTypeOf(result).toEqualTypeOf<null | { id: string | null }>()
})

test(`document with two queries`, async () => {
Expand All @@ -34,7 +34,7 @@ test(`document with two queries`, async () => {
type $Parameters = Parameters<typeof run>
expectTypeOf<$Parameters>().toEqualTypeOf<['foo' | 'bar']>()
const result = await run(`foo`)
expectTypeOf(result).toEqualTypeOf<{ id: string | null }>()
expectTypeOf(result).toEqualTypeOf<null | { id: string | null }>()
})

test(`document with two queries of different root types`, async () => {
Expand All @@ -49,7 +49,7 @@ test(`document with two queries of different root types`, async () => {
type $Parameters = Parameters<typeof run>
expectTypeOf<$Parameters>().toEqualTypeOf<['foo' | 'bar']>()
const result = await run(`foo`)
expectTypeOf(result).toEqualTypeOf<{ id: string | null }>()
expectTypeOf(result).toEqualTypeOf<null | { id: string | null }>()
})

test(`root operation not available if it is not in schema`, () => {
Expand Down
18 changes: 10 additions & 8 deletions src/documentBuilder/requestMethods/document.ts
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
import type { UnionToTuple } from 'type-fest'
import type { Simplify, UnionToTuple } from 'type-fest'
import type { Context } from '../../client/context.js'
import { type HandleOutput } from '../../client/handleOutput.js'
import type { InferResult } from '../../documentBuilder/InferResult/__.js'
Expand All @@ -18,15 +18,17 @@ export type DocumentRunner<
const $Name extends string = $Params extends [] ? $$Name : $Params[0],
>(...params: $Params) =>
Promise<
HandleOutput<
$$Context,
InferResult.Operation<
Select.Document.GetOperation<$$Document, $Name>,
$$Schema,
Select.Document.GetOperationType<$$Document, $Name>
Simplify<
HandleOutput<
$$Context,
InferResult.Operation<
Select.Document.GetOperation<$$Document, $Name>,
$$Schema,
Select.Document.GetOperationType<$$Document, $Name>
>
>
// & {}
>
& {}
>
}

Expand Down
10 changes: 10 additions & 0 deletions src/lib/prelude.ts
Original file line number Diff line number Diff line change
Expand Up @@ -738,3 +738,13 @@ export namespace Func {
: (...args: $Args) => $Output | $ReturnTypeToAdd
: never
}

export type UnionMerge<U> = {
[K in UnionKeys<U>]: UnionValue<U, K>
}

type UnionKeys<U> = U extends any ? keyof U : never

type UnionValue<U, K extends PropertyKey> = U extends any ? K extends keyof U ? U[K]
: never
: never

0 comments on commit 9119f04

Please sign in to comment.