Tighten scalar codegen types (#2554)#3085
Open
ifeanyi-ugwu wants to merge 6 commits into
Open
Conversation
CountryCode, Currency and CountryName accept only a fixed ISO set, so the generated resolver type should be that string-literal union rather than a bare `string`. The union and the jsonSchema `enum` are derived from a single `as const` source list, and each scalar carries precise generics. Matching stays case-insensitive and returns the input value unchanged.
Several scalars parse to one type but accept a wider set for serialization, so the single codegenScalarType could only ever name one of them — and sometimes named the wrong one: USCurrency claimed `string` though resolvers both return and receive `number`. codegenScalarType now consistently carries the resolver-return (output) type, with precise `<TParsed, TSerialized>` generics so the parsed type stays recoverable from the scalar itself. Timestamp's jsonSchema type is corrected to integer to match its numeric wire value.
…enerics The scalars built from inline configs defaulted to `GraphQLScalarType<unknown, unknown>`, hiding their real types. Each now declares `<string, string>` or `<number, number>` to match what parseValue and serialize actually handle, so the parsed and serialized types are visible from the scalar itself. Behavior is unchanged; SE's string guard became an assertion so it narrows without a cast.
…branch The jsonSchema.type correction (string -> integer, matching the numeric serialized value) is already carried by fix/jsonschema-definitions, the branch that owns jsonSchema definitions; duplicating it here would conflict on merge. This keeps the branch scoped to codegen types and generics — the `<Date, number>` generic and codegenScalarType are untouched.
ardatan
reviewed
Jul 10, 2026
|
|
||
| export const GraphQLSESSN: GraphQLScalarType = /*#__PURE__*/ new GraphQLScalarType({ | ||
| export const GraphQLSESSN: GraphQLScalarType<string, string> = /*#__PURE__*/ new GraphQLScalarType< | ||
| string, |
Contributor
There was a problem hiding this comment.
This might break GraphQL v15 support. And it means a breaking change then.
Contributor
Author
There was a problem hiding this comment.
yeah, i totally missed that. i've reverted the change.
it's too trivial for a breaking change. i also compiled against v14 and v15 just to be sure
`GraphQLScalarType` gained its `<TInternal, TExternal>` type parameters in graphql-js v16. In v14 and v15 the class is non-generic. The class-level `GraphQLScalarType<...>` annotations fail to typecheck there (`Type 'GraphQLScalarType' is not generic`) — a breaking change for consumers on the v14/v15 peer range, which the minor changeset did not account for. The changeset drops the removed-generics framing and the already-reverted Timestamp jsonSchema bullet.
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Gives
codegenScalarTypea single consistent meaning across scalars — theresolver-return (output) type — and emits string-literal unions for the enum
scalars. Generated resolver types then match what each scalar actually
serializes and accepts. Addresses #2554.
Why the resolver-return type
@graphql-codegen/typescriptreadscodegenScalarTypeas one string and appliesit to both the input and output slots of the generated
Scalarsmap; theextension alone cannot express input ≠ output. The resolver-return type is the
safe direction: a too-wide resolver argument type never errors, whereas a
too-narrow return type rejects code that serializes fine at runtime.
Changes
Enum scalars
as constcode list, with a matchingjsonSchema.enum, instead ofstring.codegenScalarType output type
string→number(resolvers return and receive cents as a number).Date | string | number.bigint | number | string.Config generics (
GraphQLScalarTypeConfig<TParsed, TSerialized>, generic since graphql v14)<any, any>→<number, number>.<Buffer | string | BufferJson, Buffer>→<Buffer, Buffer>.<CurrencyCode, CurrencyCode>.Compatibility
Type-level only, with no runtime behavior change. Consumers relying on the
previously looser types may see new — and correct — compile errors where a value
was typed too broadly before. The changeset is minor.