diff --git a/src/gql/fragment-masking.ts b/src/gql/fragment-masking.ts index 2ba06f1..977442e 100644 --- a/src/gql/fragment-masking.ts +++ b/src/gql/fragment-masking.ts @@ -1,8 +1,18 @@ -import { ResultOf, DocumentTypeDecoration, TypedDocumentNode } from '@graphql-typed-document-node/core'; +import { DocumentTypeDecoration, TypedDocumentNode } from '@graphql-typed-document-node/core'; import { FragmentDefinitionNode } from 'graphql'; import { Incremental } from './graphql'; +type Primitive = string | number | boolean | bigint | symbol | null | undefined; +type ExcludePrimitive = Exclude; +type ExtractPrimitive = Exclude>; +type UnionToIntersection = (U extends any ? (k: U) => void : never) extends ( + k: infer I +) => void + ? I + : never; + + export type FragmentType> = TDocumentType extends DocumentTypeDecoration< infer TType, any @@ -42,11 +52,44 @@ export function useFragment( } +type UnionToIntersectGroupByTypeName = [V] extends [ + { __typename?: infer TypeName } +] + ? TypeName extends any + ? UnionToIntersection + : never + : never; + +type UnionFieldToIntersection = [T] extends [never] ? never + : [T] extends [Array] + ? Array< + | UnionFieldToIntersection> + | ExtractPrimitive + > + : UnionToIntersectGroupByTypeName extends infer V + ? { + [Key in keyof V]: + | UnionFieldToIntersection> + | ExtractPrimitive; + } + : never; + +type Flatten = [F] extends [never] ? never + : F extends Array + ? Array> | ExtractPrimitive> + : { + [Key in keyof Omit]: + | Flatten> + | ExtractPrimitive; + } & (F extends { " $fragmentRefs"?: { [K in string]: infer FRefs }; } + ? (FRefs extends any ? Flatten : never) : {} + ); +export type UnmaskFragment = UnionFieldToIntersection>; + export function makeFragmentData< F extends DocumentTypeDecoration, - FT extends ResultOf ->(data: FT, _fragment: F): FragmentType { - return data as FragmentType; +>(data: UnmaskFragment>, _fragment: F): FragmentType { + return data as any; } export function isFragmentReady( queryNode: DocumentTypeDecoration,