Skip to content

fix(types): preserve selector returnObjects shape with context (#2398)#2438

Merged
adrai merged 1 commit into
i18next:masterfrom
sauravgupta-dotcom:fix/issue-2398-selector-context-returnobjects
Jun 26, 2026
Merged

fix(types): preserve selector returnObjects shape with context (#2398)#2438
adrai merged 1 commit into
i18next:masterfrom
sauravgupta-dotcom:fix/issue-2398-selector-context-returnobjects

Conversation

@sauravgupta-dotcom

Copy link
Copy Markdown
Contributor

Summary

Fixes the remaining TypeScript selector regression from #2398: t(selector, { returnObjects: true, context }) on heterogeneous JSON arrays was inferring a union of partial element types (or unknown) instead of preserving full object shapes such as { transKey1: string; transKey2: string }[].

Problem 2 from the issue (valid context keys erroring) was already addressed on master; this PR targets the leftover Problem 1 case and the context + plurals array regression test.

Changes

  • FilterKeys: distribute over object unions so each JSON array element is filtered independently (avoids keyof (A | B) only seeing common keys).
  • _DefinedContextKeys / _HasContextVariant / _IsContextualKey: ignore phantom optional undefined context keys that TypeScript adds when merging heterogeneous array element types (e.g. transKey1_withContext?: undefined on elements that do not define that key).
  • TFunctionSelector: add a more specific overload for context + returnObjects: true using const Context + const Fn + ReturnType<Fn>, matching the non-context selector pattern so Target is not collapsed via ConstrainTarget / ApplyTargetunknown.
  • Tests: promote test/typescript/selector-issue-2398/ from .todo to real expectTypeOf assertions (including context + plurals on array elements).

Test plan

  • Local commit includes regression tests in test/typescript/selector-issue-2398/t.test.ts
  • npx vitest --config vitest.workspace.typescript.mts run test/typescript/selector-issue-2398
  • npx vitest --config vitest.workspace.typescript.mts run (full TypeScript workspace)
  • Spot-check existing selector context cases in test/typescript/selector/ still pass

Fixes #2398

…xt#2398)

Context + returnObjects on the selector API was losing properties on
heterogeneous JSON array elements and inferring unknown for Target.
Distribute FilterKeys over unions, ignore phantom optional context keys,
and add a dedicated context+returnObjects overload using const Fn inference.
@sauravgupta-dotcom

Copy link
Copy Markdown
Contributor Author

Review request (API could not assign reviewers from this fork account — please take a look if you have a moment):

Labels intended for this PR (matching the issue): typescript, help wanted.

@coveralls

Copy link
Copy Markdown

Coverage Status

coverage: 94.985%. remained the same — sauravgupta-dotcom:fix/issue-2398-selector-context-returnobjects into i18next:master

@adrai adrai merged commit 9cbfa63 into i18next:master Jun 26, 2026
9 checks passed
adrai added a commit that referenced this pull request Jun 26, 2026
@adrai

adrai commented Jun 26, 2026

Copy link
Copy Markdown
Member

Merged and released in v26.3.3 🎉 Thanks @sauravgupta-dotcom!

Before merging I verified the change end-to-end:

  • Targeted tests: the promoted selector-issue-2398 assertions pass (both property presence and string value types, including the context + plurals case).
  • Full TS workspace: all 499 type tests across 63 files pass with no type errors, so no regression in the existing selector / plural / context / namespace cases.
  • No behavioral drift anywhere: diffed the exact tsc error set across the whole test/typescript corpus before vs. after. The intentional negative tests (@ts-expect-error etc.) act as a large assertion surface, and the set is identical (valid code still checks, invalid code still errors).
  • Type-checker cost: measured with tsc --extendedDiagnostics, +3.7% instantiations / +3.4% types from the extra _DefinedContextKeys mapped type and the FilterKeys union distribution, with no measurable wall-clock change. Runtime is unaffected (.d.ts-only, zero JS emitted).

The FilterKeys union-distribution fix is a nice general correctness improvement beyond just this case. Appreciate the thorough writeup and regression tests 🙏

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.

Incorrect type narrowing when combining returnObjects: true and context with selector syntax

3 participants