Skip to content

fix(typescript): annotate m() helper's props array to satisfy noImplicitAny#2977

Merged
schani merged 1 commit into
masterfrom
agent/fix-issue-2430
Jul 21, 2026
Merged

fix(typescript): annotate m() helper's props array to satisfy noImplicitAny#2977
schani merged 1 commit into
masterfrom
agent/fix-issue-2430

Conversation

@schani

@schani schani commented Jul 20, 2026

Copy link
Copy Markdown
Member

Bug

The shared JavaScript/TypeScript/Flow runtime-typecheck helper m() (used whenever the generated model contains a map/dictionary-typed object, i.e. an object with arbitrary/unknown keys all sharing one value type) emitted an untyped array literal:

function m(additional: any) {
    return { props: [], additional };
}

Compiling TypeScript output with --noImplicitAny (and strictNullChecks: false, which is TypeScript's default) fails with:

error TS7018: Object literal's property 'props' implicitly has an 'any[]' type.

Root cause

packages/quicktype-core/src/language/JavaScript/JavaScriptRenderer.ts emits both an o() helper (typed object with a known property list) and an m() helper (map type). o()'s props parameter is typed via the renderer's existing conditional type-annotation mechanism (this.typeAnnotations, which resolves to ": any[]" in TS/Flow mode and "" in plain JS mode). m()'s inline [] literal never went through that mechanism, so under noImplicitAny TypeScript couldn't widen it past never[].

Fix

Reuse the same anyArrayAnnotation mechanism o() already uses, by declaring props as a local variable instead of an inline literal:

function m(additional: any) {
    const props: any[] = [];
    return { props, additional };
}

This is valid TypeScript, valid Flow (since anyArrayAnnotation is "" there... actually Flow gets ": any[]" too and this syntax is valid Flow), and plain JavaScript output is untouched (anyArrayAnnotation is "" there, so it stays const props = [];).

Test coverage

  • test/fixtures/typescript/tsconfig.json now sets "noImplicitAny": true and "strictNullChecks": false, matching the exact compiler flags from the bug report, so the typescript fixture's tsc -p . compile step actually exercises this check (previously TypeScript's default noImplicitAny: false silently masked the bug for every existing sample).
  • test/inputs/json/priority/number-map.json already exercises the m() helper (an object with arbitrary punctuation-heavy keys, inferred as a map) and is part of the typescript fixture's always-run priority set, so no new input file was needed.

Verification

  • Confirmed the bug is exposed on unfixed code: reverted just the renderer change, rebuilt, and ran
    QUICKTEST=true FIXTURE=typescript script/test test/inputs/json/priority/number-map.json → failed with TS7018 via tsc -p ..
  • Re-applied the fix, rebuilt, and reran the same command → passes.
  • Ran the full QUICKTEST=true FIXTURE=typescript script/test (78 tests) → all pass.
  • Ran QUICKTEST=true FIXTURE=javascript script/test test/inputs/json/priority/number-map.json → passes (plain JS output unaffected).
  • Manually generated Flow output (--lang flow) for the same sample and confirmed the emitted m() helper is valid Flow syntax.
  • Reproduced the original reporter's exact repro (quicktype -s json sample.json -o out.ts then tsc --noImplicitAny --strictNullChecks false --noEmit out.ts) before and after the fix — TS7018 before, clean compile after.
  • npm run build passes.

Fixes #2430

🤖 Generated with Claude Code

…citAny (#2430)

Co-Authored-By: gpt-5.6-sol via pi <noreply@openai.com>
@schani
schani merged commit cbd196d into master Jul 21, 2026
28 checks passed
@schani
schani deleted the agent/fix-issue-2430 branch July 21, 2026 00:36
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

TS7018 error in generated typescript

1 participant