-
Hi everyone, I'm trying to find the best practice for generating precise TypeScript types for our input fields, as we have two distinct and conflicting use cases: filtering and mutations. 1. The Filtering Use Case (Optional but Non-Nullable) For query inputs used in filtering, we want fields to be optional, but if a value is provided, it should never be I would love to enforce this at the type level. The ideal approach (I think) would be to use a directive in the schema: directive @nonNullable on INPUT_FIELD_DEFINITION
input ProductFilterInput {
# If provided, sku must be a string, not null.
sku: String @nonNullable
# If provided, inStock must be a boolean, not null.
inStock: Boolean @nonNullable
} This would ideally generate a strict TypeScript type where null is not permitted: // Desired generated type for filtering
export type ProductFilterInput = {
sku?: string;
inStock?: boolean;
}; 2. The Mutation Use Case (Optional and Nullable) At the same time, we need to preserve the standard behavior for our mutation inputs. In mutations, sending null is a critical feature that allows clients to clear or unset a value in the database. input UpdateUserInput {
# This field can be explicitly set to null to clear the user's bio.
bio: String
} This requires the default, less strict generated type: // Desired generated type for mutations
export type UpdateUserInput = {
bio?: string | null;
}; The Core Problem Because of these two conflicting requirements, updating the global configuration This leads me to believe a directive-based approach is the correct path, as it provides the field-level granularity we need. My question is: Is there a current configuration option within the If a direct configuration for this doesn't exist, I'd be very interested to understand if this is an intentional design choice. Is the recommended path to implement a more complex solution with custom mappers, or are there other patterns for solving this common problem? Thanks for any guidance or best practices you can share! |
Beta Was this translation helpful? Give feedback.
Replies: 1 comment 1 reply
-
Hi @jkepps , thanks for bringing up this interesting use case. TLDR; we currently don't have a way to change types based on custom directives (with some exceptions). For scenario 1, I'm curious if you'd do a check in your server to handle Enforcing input type may work for one client, but there are some scenarios to consider:
Scenario 2 seems like the typical nullability use case 👍
To keep Codegen light and maintainable, we generally implement type based on GraphQL spec, or certain directives such as Slight tangent is about the naming of |
Beta Was this translation helpful? Give feedback.
Hi @jkepps , thanks for bringing up this interesting use case.
TLDR; we currently don't have a way to change types based on custom directives (with some exceptions).
For scenario 1, I'm curious if you'd do a check in your server to handle
null
before passing it on to the ORM?Enforcing input type may work for one client, but there are some scenarios to consider:
null
. So it still may be safer for the server to handlenull
anyways. To me, this would be the best practiceScenario 2 seems like the typical nullability use case 👍