`Select` with `multiple` and object values infers `T` as `Item | Item[]`

Open
#528 0 comments 0 reactions 0 assignees View on GitHub

Maintainers usually reply within 1 day

Nobody has claimed this yet.

Assessment

Difficulty
3/5
Estimated time
1-2 days
Newbie friendliness
52/100
Issue type
Bug
Clarity
Clearly specified
Activity status
Active
Tech stack
typescript
Domain
frontend

Research direction

Start with the Select generic signature and the SelectOptions type, where value is typed T | T[] in the either branch and T[] in the multiple branch, and see how inference picks up both. Run the four snippets in the issue with bunx tsc before and after. Done when T infers as { id: number } for the multiple case, itemToValue gets a single item, and onValueChange receives { id: number }[], with the single-value and string cases unchanged.

Written by the indexing model from the issue text.

Description

What happens

With multiple: true and object values, TypeScript infers T from both the multiple branch
(value: T[]) and the either branch of SelectOptions (value: T | T[]), so T becomes
Item[] | Item: itemToValue's parameter and onValueChange's value are typed with the union.
With string values, or a single object value, T is the item type as expected.

Minimal reproduction
import { Select } from '@ui-sdk/solid/select'

// error TS2339: Property 'id' does not exist on type '{ id: number; }[] | { id: number; }'.
Select({ multiple: true, value: [{ id: 1 }], itemToValue: (m) => String(m.id) })

// value: ({ id: number }[] | { id: number })[], not { id: number }[]
Select({ multiple: true, value: [{ id: 1 }], onValueChange: (value) => value })

// fine: T is { id: number } / string
Select({ value: { id: 1 }, itemToValue: (m) => String(m.id) })
Select({ multiple: true, value: ['a'], onValueChange: (value) => value })
Versions

@ui-sdk/solid 0.1.0-beta.1, @ui-sdk/core 0.1.0-beta.1, TypeScript 6 (bunx tsc).

Expected behavior

T is { id: number } and itemToValue's parameter is typed as one item, as in the
single-value case. Writing Select<{ id: number }, true> works around it.


Reproduced on @ui-sdk/core / @ui-sdk/solid 0.1.0-beta.2.

Dominant language
TypeScript
Stars
4.4k
Forks
122
Avg merge
3h 12m
Merged PRs (30d)
437

Getting set up

First steps

  1. Read the whole issue, then the project's contributing guide.
  2. Comment on the issue to say you are picking it up — it saves two people doing the same work.
  3. Fork the repository and make your change on a branch.
  4. Open a pull request that references the issue number.

More from vercel-labs/ui

All issues in vercel-labs/ui

Similar issues

More TypeScript issues

Get new issues in your inbox

A short digest of beginner-friendly GitHub issues.