Skip to content

fix(types): resolve GetItemKeys / GetItemValue with branded and complex types#6073

Open
NaxelaRed wants to merge 1 commit intonuxt:v4from
NaxelaRed:fix/get-item-keys-branded-types
Open

fix(types): resolve GetItemKeys / GetItemValue with branded and complex types#6073
NaxelaRed wants to merge 1 commit intonuxt:v4from
NaxelaRed:fix/get-item-keys-branded-types

Conversation

@NaxelaRed
Copy link

Description

Fixes #6072

GetItemKeys<I> and GetItemValue rely on NestedItem<T>, a recursive conditional type. When item types contain branded types, complex intersections, or readonly symbol properties, TypeScript defers evaluation of NestedItem<T> — the resulting type becomes opaque and concrete string keys like "id" or "name" are no longer assignable to GetItemKeys<I>. This also breaks v-model inference through GetModelValue.

Changes

Added a non-recursive _FlatItem<I> helper that performs a simple 2-level array unwrap. Since it's non-recursive, TypeScript can always eagerly resolve it.

  • GetItemKeys: added keyof Extract<_FlatItem<I>, object> as the first union member (fast-path). NestedItem and DotPathKeys are kept as fallbacks so deeply nested arrays continue to work.
  • GetItemValue: changed the default type parameter from NestedItem<I> to _FlatItem<I>, and added a keyof T fast-path before the DotPathKeys branch.

Why a new type instead of fixing NestedItem?

NestedItem is recursive by design — it handles arbitrarily nested arrays (T[][][]...). TypeScript's deferred evaluation of recursive conditional types is expected behavior and cannot be avoided. _FlatItem provides an eagerly-resolvable alternative for the common case (1-2 levels of array nesting) while keeping NestedItem for the general case.

Testing

Verified that:

  • Branded types (T & { readonly [symbol]: B }) now work with value-key, label-key, and v-model on USelect, USelectMenu, and UInputMenu
  • Standard (non-branded) types continue to work as before
  • Deeply nested arrays (T[][]) still resolve correctly through the NestedItem fallback

…ex types

Add a non-recursive `_FlatItem<I>` helper as a fast-path for
`GetItemKeys` and `GetItemValue`. TypeScript defers evaluation of the
recursive `NestedItem<T>` when item types contain branded or complex
intersections, making `GetItemKeys` opaque and preventing concrete
string keys from being assignable.

`_FlatItem` performs a simple 2-level array unwrap that TypeScript can
always eagerly evaluate. `NestedItem` and `DotPathKeys` are kept as
fallbacks so deeply nested arrays continue to work.

Fixes nuxt#6072
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

Projects

None yet

Development

Successfully merging this pull request may close these issues.

GetItemKeys / GetItemValue fail to resolve with branded or complex item types

2 participants

Comments