Repository navigation
[visitor-plugin-common] fix: satisfy strict mode in utils and the remaining files (#4683) - #11039
Conversation
…aining files (#4683) Widen transformComment, buildScalars, buildTypeImport (now throws on a missing identifier/source), DeclarationBlock fields/withBlock and ParsedEnumValuesMap to accept nullish values; getName/transform/buildSelectionSetFromStrings may return null. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01N2WHcqFc3QgDV5mTdEiuGv eddeee888:oss:issue-fix
…angeset Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01N2WHcqFc3QgDV5mTdEiuGv
…-types-visitor Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01N2WHcqFc3QgDV5mTdEiuGv
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01N2WHcqFc3QgDV5mTdEiuGv
🦋 Changeset detectedLatest commit: f6a1521 The changes in this PR will be included in the next version bump. This PR includes changesets to release 1 package
Not sure what this means? Click here to learn what changesets are. Click here if you're a maintainer who wants to add another changeset to this PR |
| .withContent( | ||
| '\n' + | ||
| node.values | ||
| (node.values || []) |
There was a problem hiding this comment.
Note: values is optional on EnumTypeDefinitionNode, and this function is exported, so a caller can pass in a node that has none. That makes || [] real handling, which is why it has no comment. Each if branch returns early and reads node.values only once, so the fallback stays inline in each branch (same at L98, L133 and L167) instead of going in a local at the top.
Generated by Claude Code
| ? (schema.getType(typeName) as GraphQLEnumType) | ||
| : undefined; | ||
| const schemaType = schema?.getType(typeName); | ||
| const schemaEnumType = isEnumType(schemaType) ? schemaType : undefined; |
There was a problem hiding this comment.
Note: This uses an isEnumType guard instead of the as GraphQLEnumType cast, so the narrowing is checked rather than asserted. If a schema type with this name isn't an enum, it's treated as having no schema enum instead of crashing on .getValue. That's also why isEnumType is now a value import, with inline type specifiers for the rest.
Generated by Claude Code
| schemaEnumType && !ignoreEnumValuesFromSchema | ||
| ? schemaEnumType.getValue(enumOption.name.value).value | ||
| : undefined; | ||
| let schemaEnumValue; |
There was a problem hiding this comment.
Note: The ternary became a let and an if, because throwing on a missing enum value needs a statement. The let has no annotation: TypeScript infers its type from the assignment below.
Generated by Claude Code
| importIdentifier?: string | null; | ||
| sourceIdentifier?: string | null; | ||
| sourceFile?: string | null; |
There was a problem hiding this comment.
Note: These are the params of the nested handleEnumValueMapper, not of the exported getEnumsImports, whose signature is unchanged. They're optional to match the ParsedEnumValuesMap fields that get passed straight in.
Generated by Claude Code
|
|
||
| export function transformMappers( | ||
| rawMappers: RawResolversConfig['mappers'], | ||
| rawMappers: RawResolversConfig['mappers'] = {}, |
There was a problem hiding this comment.
Note: I gave the param a default instead of adding || {} inside the function, because mappers is optional in the raw config. Callers that pass undefined get an empty map, and the body stays as it was.
Generated by Claude Code
|
|
||
| public get string(): string { | ||
| let result = ''; | ||
| const blockTransformer = this._config.blockTransformer || (block => block); |
There was a problem hiding this comment.
Note: The fallback is in the getter rather than the constructor's defaults. The constructor spreads the caller's config over the defaults, so an explicit blockTransformer: undefined still gets through. A single local here covers all three call sites below.
Generated by Claude Code
| // dropping support for older graphql versions | ||
| (((namedType as unknown as Record<'isOneOf', boolean | undefined>).isOneOf || | ||
| namedType.astNode?.directives?.some(d => d.name.value === 'oneOf')) ?? | ||
| false); |
There was a problem hiding this comment.
Note: The ?? false is needed because astNode?.directives?.some(...) gives undefined when there are no directives, and the cache is a Map<…, boolean>. Callers only check truthiness, so caching false doesn't change what they get.
Generated by Claude Code
| export function unique<T>( | ||
| array: Array<T>, | ||
| key: (item: T) => string | number = item => item.toString(), | ||
| key: (item: T) => string | number = item => String(item), |
There was a problem hiding this comment.
Note: T is unconstrained, so under strict TypeScript doesn't know item.toString() exists. String(item) gives the same key for the strings and numbers this is used with.
Generated by Claude Code
…port Co-Authored-By: Claude Haiku 5.5 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01N2WHcqFc3QgDV5mTdEiuGv
…dated base Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01N2WHcqFc3QgDV5mTdEiuGv
Description
Part 3b, the last part of the strict-mode work tracked in #10985. It fixes the 46 errors left in
visitor-plugin-commonthatstrict: trueraises, inutils,imports,naming,mappers,types,variables-to-object,convert-schema-enum-to-declaration-block-string,selection-set-processor/baseandoptimize-operations. With this PR, #10985's stricttsconfig.jsontypechecks with 0 errors.Related #4683
As in #11030 and #11037, types are widened where they're declared, with no new
ascasts or!:transformCommentandblockacceptnull/undefined,buildScalarsacceptsundefined, andDeclarationBlock.withBlockacceptsnull. Each already handles that value.DeclarationBlock's fields initialised tonullare typed asstring | null.ParsedEnumValuesMap'smappedValues,sourceIdentifier,sourceFileandimportIdentifieracceptnull, whichparseEnumValuesalready emits.OperationVariablesToObject.getName/transformandBaseSelectionSetProcessor.buildSelectionSetFromStringsreturnstring | null, which they already return.buildTypeImport,buildEnumValuesBlockandoptimizeOperationsthrow a descriptive error where they used to crash or emitundefined.values,identifiers,@deprecatedarguments) are treated as empty instead of throwing, andDeclarationBlockreturns the block unchanged whenblockTransformerisundefined.naming.tsdrops itsascasts by holdingnamingConventionin a narrowed local. The only cast in the lines this PR touches is inisOneOfInputObjectType, with a comment:isOneOfexists only from graphql 16.9.transformCommentacceptsundefined,base-types-visitordrops the|| ''it needed in [visitor-plugin-common] fix: satisfy strict mode in base-types-visitor (#4683) #11037.The changeset lists every public signature and behaviour change. One change to emitted text:
OperationVariablesToObjectnow emits''instead of the textundefined/nullwhen a variable has no name or type identifier. No current input reaches that case.Type of change
How Has This Been Tested?
visitor-plugin-common,typescript,operations,resolvers,document-nodes,typed-document-node,client-preset,graphql-modules-preset)pnpm dev-test:generategives no diff, so generated output for the dev-tests is unchangedpnpm exec tsc --noEmit -p tsconfig.jsonwith chore: enablestrict: truein root tsconfig (#4683) #10985's stricttsconfig.jsongives 0 errors (46 onmaster)Further comments
Once this merges, every box in #10985's checklist is ticked, and #10985 can be rebased and merged to turn on
strict: true.Like #11030 and #11037, this is marked as a bug fix. The
string | nullreturn types only widen what these methods already return at runtime, but downstream TypeScript users withstrictNullChecksmay need to handlenullwhere they call them.🤖 Generated with Claude Code