Skip to content

Commit

Permalink
Add isOneOf typing on builder.inputObject
Browse files Browse the repository at this point in the history
  • Loading branch information
hayes committed Aug 10, 2024
1 parent d5f989b commit 8219539
Show file tree
Hide file tree
Showing 6 changed files with 58 additions and 3 deletions.
5 changes: 5 additions & 0 deletions .changeset/smooth-parents-punch.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
---
"@pothos/core": minor
---

Add proper typeing for isOneOf option on builder.inputType
16 changes: 13 additions & 3 deletions packages/core/src/builder.ts
Original file line number Diff line number Diff line change
Expand Up @@ -55,6 +55,7 @@ import type {
ObjectFieldsShape,
ObjectParam,
ObjectTypeOptions,
OneOfInputShapeFromFields,
OutputShape,
ParentShape,
PluginConstructorMap,
Expand Down Expand Up @@ -583,18 +584,27 @@ export class SchemaBuilder<Types extends SchemaTypes> {
: Param extends keyof Types['Inputs']
? InputFieldsFromShape<Types, InputShape<Types, Param> & object, 'InputObject'>
: InputFieldMap,
IsOneOf extends boolean = boolean,
>(
param: Param,
options: PothosSchemaTypes.InputObjectTypeOptions<Types, Fields>,
): PothosSchemaTypes.InputObjectRef<Types, InputShapeFromFields<Fields>> {
options: PothosSchemaTypes.InputObjectTypeOptions<Types, Fields> & {
isOneOf?: IsOneOf;
},
): PothosSchemaTypes.InputObjectRef<
Types,
[IsOneOf] extends [true] ? OneOfInputShapeFromFields<Fields> : InputShapeFromFields<Fields>
> {
verifyRef(param);
const name = typeof param === 'string' ? param : (param as { name: string }).name;

const ref = (
typeof param === 'string'
? new InputObjectRef<Types, InputShapeFromFields<Fields>>(name)
: param
) as PothosSchemaTypes.InputObjectRef<Types, InputShapeFromFields<Fields>>;
) as PothosSchemaTypes.InputObjectRef<
Types,
[IsOneOf] extends [true] ? OneOfInputShapeFromFields<Fields> : InputShapeFromFields<Fields>
>;

ref.updateConfig({
kind: 'InputObject',
Expand Down
14 changes: 14 additions & 0 deletions packages/core/src/types/builder-options.ts
Original file line number Diff line number Diff line change
Expand Up @@ -24,6 +24,7 @@ import type {
Normalize,
NormalizeNullableFields,
RemoveNeverKeys,
Simplify,
} from './utils';

export type AddVersionedDefaultsToBuilderOptions<
Expand Down Expand Up @@ -211,6 +212,19 @@ export type ValidateInterfaces<
: 'Object shape must extend interface shape'
: never;

export type OneOfInputShapeFromFields<Fields extends InputFieldMap> =
keyof Fields extends infer K extends keyof Fields
? K extends unknown
? Simplify<
{
[Name in K]: NonNullable<InputShapeFromField<Fields[K]>>;
} & {
[Name in keyof Fields as Name extends K ? never : Name]?: never;
}
>
: never
: never;

export type InputShapeFromFields<Fields extends InputFieldMap> = NormalizeNullableFields<{
[K in string & keyof Fields]: InputShapeFromField<Fields[K]>;
}>;
Expand Down
2 changes: 2 additions & 0 deletions packages/core/src/types/utils.ts
Original file line number Diff line number Diff line change
Expand Up @@ -138,3 +138,5 @@ export interface PartialResolveInfo {
variableValues: GraphQLResolveInfo['variableValues'];
schema: GraphQLResolveInfo['schema'];
}

export type Simplify<T> = { [KeyType in keyof T]: T[KeyType] } & {};
6 changes: 6 additions & 0 deletions packages/core/tests/__snapshots__/index.test.ts.snap
Original file line number Diff line number Diff line change
Expand Up @@ -66,9 +66,15 @@ input NestedListInput {
list: [[Int!]]!
}
input OneOfExample @oneOf {
a: String
b: String
}
type Query {
constructor: Boolean
nestedLists(input: [[[String!]!]]!, nestedListInput: NestedListInput): [[[String!]!]]
oneOf(oneOf: OneOfExample!): String!
sheep: Sheep
stuff: [stuff!]
user: User
Expand Down
18 changes: 18 additions & 0 deletions packages/core/tests/examples/random-stuff.ts
Original file line number Diff line number Diff line change
Expand Up @@ -346,6 +346,24 @@ builder.queryType({
shaved: true,
}),
}),
oneOf: t.string({
args: {
oneOf: t.arg({
required: true,
type: builder.inputType('OneOfExample', {
isOneOf: true,
fields: (t) => ({
a: t.string(),
b: t.string(),
}),
}),
}),
},
nullable: false,
resolve: (_, { oneOf }) => {
return oneOf.a ?? oneOf.b;
},
}),
}),
});

Expand Down

0 comments on commit 8219539

Please sign in to comment.