Skip to content

[type-safety] Push ArtifactKind/ArtifactStatus discriminated unions through Filters widget #98

@fedorovvvv

Description

@fedorovvvv

Source: PRD-018 SC-2 audit, Type [W1].

template/src/widgets/artifact-filters/ui/Filters.svelte:5-15

let {
  kinds = [],
  status = [],
  kindFilter = $bindable(new Set<string>()),
  statusFilter = $bindable(new Set<string>()),
  ...
} = $props();

The widget exists to filter by kind and status, both of which are discriminated string unions defined in entities/artifact/model/types.ts (ArtifactKind, ArtifactStatus). Typing them as string[] / Set<string> throws away exhaustiveness:

  • A <ToggleGroup type="multiple"> could fire any string and the parent silently accepts it.
  • HomePage's n.kind.toLowerCase() returns string and there's no guard that the lowercased form is one of the canonical kinds.

Fix

  • Tighten Filter props: kinds?: ArtifactKind[]; kindFilter?: Set<ArtifactKind> (analogous for status).
  • Either:
    • Make Filters accept the canonical-cased kinds and lowercase only at presentation, OR
    • Declare type LowercaseArtifactKind = Lowercase<ArtifactKind> and use it consistently.

Acceptance

  • npm run check clean.
  • A wrong-cased kind passed to Filters is a compile error.
  • Exhaustiveness check on kindLabel(k) / kindColor(k) lights up if ArtifactKind grows.

Related

  • Type-safety [W7] in HomePage breach loop — same exhaustiveness gap, can be fixed in this issue or separately.

Audit traceability

  • Reviewer: TypeScript-pro

Metadata

Metadata

Assignees

No one assigned

    Labels

    Type

    No type
    No fields configured for issues without a type.

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions