Skip to content

finding(plugin-list): ListViewProps.onSortChange / onFilterChange are declared any, so a documented callback example compiles without either parameter being checked #8106

Description

@baozhoutao

Found while paying down packages/plugin-list/README.md for objectui#5174 (batch 24). Filed, not fixed: the fix touches packages/** source and moves a public type, which that batch's licence excludes.

Notation: this body spells generic and JSX shapes out in words rather than in their angle-bracket form, because this repository has measured that GitHub's body sanitizer deletes tag-shaped fragments even inside backticks.

What was measured

packages/plugin-list/dist/ListView.d.ts declares the four callbacks the README's "With Callbacks" example passes:

onViewChange?: (view: ViewType) => void;
onFilterChange?: (filters: any) => void;
onSortChange?: (sort: any) => void;
onSearchChange?: (search: string) => void;

Before batch 24 the README block raised TS7006 (implicit any) on all four parameters, because the block never imported ListView and so had no contextual type at all. Adding a real self-import binds the element to ListViewProps and all four TS7006 go away — but they go away for two different reasons, and only two of them become real checks.

Measured directly, by assigning each parameter to a number inside the block and running pnpm check:doc-snippets:

parameter contextual type assigning it to a number
view ViewType TS2322 — checked
search string TS2322 — checked
sort any no diagnostic — not checked
filters any no diagnostic — not checked

So for onSortChange and onFilterChange the doc gate now reports green on a block whose parameters nothing constrains. That is honest about the gate (it compiles) and misleading as coverage (two of the four documented callbacks are unverifiable by construction).

Why this looks like an oversight rather than a decision

The ListViewProps doc comment in the same file is unusually explicit about exactly this hazard — it records objectui#4528, where a string index signature erased the whole interface and typed onRowClick as any while the interface went on declaring a real signature. The sweep that followed named each prop "at the type each one actually lands on". dataSource?: any carries its own written justification right there. onSortChange and onFilterChange carry none.

There is a plausible real type for each within the package: parseSortConfig returns SortItem[] (imported from @object-ui/components), and the filter side already has FilterGroup and the array/triplet filter AST that normalizeFilters and buildEffectiveFilter speak.

Why it is not decided here

Narrowing either one is a public-type change with a consumer sweep (ObjectView, StudioDesignSurface and the app-shell hosts pass these), so it wants its own card and its own triage. Two questions for whoever takes it:

  1. Which shipped type is the right one for each — for sort, SortItem[] as parseSortConfig returns, or the raw declaration shape the schema carries; for filters, FilterGroup or the filter AST.
  2. Whether the callbacks fire with the normalized value or the raw one — the answer decides question 1 and is a read of ListView's call sites, not of the declaration.

Related: objectui#4528 (the index-signature erasure this interface's comment documents), objectui#5174 (the ungated-docs burn-down this was found under).

Activity

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

Metadata

Metadata

Assignees

No one assigned

    Labels

    bugSomething isn't workingdomain:uiobjectui ui stream: fix lands on the published library or apps — objectui execution seatpluginpriority:p3

    Type

    Projects

    No projects

      Milestone

      No milestone

      Relationships

      None yet

      Development

      No branches or pull requests

      Issue actions