Skip to content

πŸ› Fix 'any' type usage β€” rebased type safety PR with conflict resolution#4098

Merged
clubanderson merged 1 commit intomainfrom
fix/type-safety-rebase
Apr 1, 2026
Merged

πŸ› Fix 'any' type usage β€” rebased type safety PR with conflict resolution#4098
clubanderson merged 1 commit intomainfrom
fix/type-safety-rebase

Conversation

@clubanderson
Copy link
Copy Markdown
Collaborator

Summary

Rebases and fixes the type safety improvements from #4085 (which had merge conflicts with #4062).

  • 3 source files: any β†’ unknown/proper types (useMarketplace, useNightlyE2EData, kubectlProxy)
  • 62 test files: replace {} as any with typed props
  • Fixed 5 type errors from the anyβ†’unknown change (optional field narrowing, unknown data guards)

Supersedes #4085.

Test plan

  • tsc --noEmit passes (verified locally)
  • Build passes
  • All existing tests pass

Rebased the type safety PR (#4085) on current main to resolve merge
conflicts with the component split (#4062). Also fixed 5 new type
errors introduced by the any→unknown change:
- kubectlProxy.ts: guard optional waitReason with ?? ''
- Marketplace.tsx: narrow unknown data with type guard before access

Original changes (from Copilot):
- 3 source files: any β†’ unknown/proper types
- 62 test files: remove {} as any spreads, use typed props

Signed-off-by: Andrew Anderson <andy@clubanderson.com>
Copilot AI review requested due to automatic review settings April 1, 2026 11:24
@kubestellar-prow kubestellar-prow bot added the dco-signoff: yes Indicates the PR's author has signed the DCO. label Apr 1, 2026
@clubanderson clubanderson merged commit 877eedd into main Apr 1, 2026
1 check passed
@kubestellar-prow
Copy link
Copy Markdown
Contributor

[APPROVALNOTIFIER] This PR is NOT APPROVED

This pull-request has been approved by:
Once this PR has been reviewed and has the lgtm label, please assign clubanderson for approval. For more information see the Code Review Process.

The full list of commands accepted by this bot can be found here.

Details Needs approval from an approver in each of these files:

Approvers can indicate their approval by writing /approve in a comment
Approvers can cancel approval by writing /approve cancel in a comment

@netlify
Copy link
Copy Markdown

netlify bot commented Apr 1, 2026

βœ… Deploy Preview for kubestellarconsole ready!

Name Link
πŸ”¨ Latest commit df614c1
πŸ” Latest deploy log https://app.netlify.com/projects/kubestellarconsole/deploys/69cd00781ee8710008bd7f14
😎 Deploy Preview https://deploy-preview-4098.console-deploy-preview.kubestellar.io
πŸ“± Preview on mobile
Toggle QR Code...

QR Code

Use your smartphone camera to open QR code link.

To edit notification comments on pull requests, go to your Netlify project configuration.

@kubestellar-prow kubestellar-prow bot deleted the fix/type-safety-rebase branch April 1, 2026 11:24
@github-actions
Copy link
Copy Markdown
Contributor

github-actions bot commented Apr 1, 2026

πŸ‘‹ Hey @clubanderson β€” thanks for opening this PR!

πŸ€– This project is developed exclusively using AI coding assistants.

Please do not attempt to code anything for this project manually.
All contributions should be authored using an AI coding tool such as:

This ensures consistency in code style, architecture patterns, test coverage,
and commit quality across the entire codebase.


This is an automated message.

@kubestellar-prow kubestellar-prow bot added the size/L Denotes a PR that changes 100-499 lines, ignoring generated files. label Apr 1, 2026
@github-actions
Copy link
Copy Markdown
Contributor

github-actions bot commented Apr 1, 2026

Thank you for your contribution! Your PR has been merged.

Check out what's new:

Stay connected: Slack #kubestellar-dev | Multi-Cluster Survey

Copy link
Copy Markdown
Contributor

Copilot AI left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Pull request overview

Rebases and reapplies prior type-safety work by removing explicit any usage in key hooks/libs and updating many React component tests to pass typed props instead of {} as any.

Changes:

  • Replaced any with unknown / concrete interfaces in useMarketplace, useNightlyE2EData, and kubectlProxy.
  • Added runtime/type guards where needed for unknown data access (notably marketplace dashboard install flow).
  • Updated a large set of unit tests to render components with valid typed props instead of {} as any.

Reviewed changes

Copilot reviewed 66 out of 66 changed files in this pull request and generated 2 comments.

Show a summary per file
File Description
web/src/lib/kubectlProxy.ts Replaces any[] pod parsing with a concrete RawPodItem interface and safer nullish handling.
web/src/hooks/useNightlyE2EData.ts Uses NightlyGuideStatus / NightlyRun types in guide/run mapping.
web/src/hooks/useMarketplace.ts Changes install result payload type from any to unknown.
web/src/components/marketplace/Marketplace.tsx Adds guards/casts for unknown install result data when installing dashboards.
web/src/components/ui/tests/StatBlockModePicker.test.tsx Replaces {} as any with explicit props.
web/src/components/ui/tests/RotatingTip.test.tsx Replaces {} as any with explicit props.
web/src/components/ui/tests/ProgressRing.test.tsx Replaces {} as any with explicit props.
web/src/components/ui/tests/LogoWithStar.test.tsx Removes {} as any in favor of default render.
web/src/components/ui/tests/FlashingValue.test.tsx Replaces {} as any with explicit props.
web/src/components/ui/tests/FeatureHintTooltip.test.tsx Replaces {} as any with explicit props.
web/src/components/ui/tests/ConsoleAIIcon.test.tsx Removes {} as any in favor of default render.
web/src/components/ui/tests/CollapsibleSection.test.tsx Replaces {} as any with explicit required props/children.
web/src/components/shared/tests/DashboardHeader.test.tsx Replaces {} as any with explicit props, wrapped in router.
web/src/components/settings/sections/tests/ProfileSection.test.tsx Replaces {} as any with explicit props.
web/src/components/settings/sections/tests/GitHubTokenSection.test.tsx Replaces {} as any with explicit props.
web/src/components/settings/sections/tests/AISettingsSection.test.tsx Replaces {} as any with explicit props.
web/src/components/settings/sections/tests/AgentSection.test.tsx Replaces {} as any with explicit props.
web/src/components/settings/sections/tests/AgentBackendSettings.test.tsx Replaces {} as any with explicit props.
web/src/components/settings/sections/tests/AccessibilitySection.test.tsx Replaces {} as any with explicit props.
web/src/components/rewards/tests/CoinDisplay.test.tsx Removes {} as any in favor of default render.
web/src/components/missions/browser/tests/EmptyState.test.tsx Replaces {} as any with explicit props.
web/src/components/missions/tests/ResolutionHistoryPanel.test.tsx Removes {} as any in favor of default render.
web/src/components/mission-control/svg/tests/DependencyPath.test.tsx Replaces {} as any with explicit props and SVG wrapper.
web/src/components/mission-control/svg/tests/BlueprintDefs.test.tsx Replaces {} as any with explicit props and SVG wrapper.
web/src/components/layout/mission-sidebar/tests/TypingIndicator.test.tsx Removes {} as any in favor of default render.
web/src/components/layout/tests/SnoozedCards.test.tsx Removes {} as any in favor of default render.
web/src/components/drilldown/views/pod-drilldown/tests/PodOutputTab.test.tsx Replaces {} as any with explicit props.
web/src/components/drilldown/views/pod-drilldown/tests/PodLabelsTab.test.tsx Replaces {} as any with explicit props.
web/src/components/drilldown/views/pod-drilldown/tests/PodDeleteSection.test.tsx Replaces {} as any with explicit props.
web/src/components/drilldown/views/pod-drilldown/tests/PodAiAnalysis.test.tsx Replaces {} as any with explicit props.
web/src/components/drilldown/views/tests/ServiceAccountDrillDown.test.tsx Removes as any from typed data prop.
web/src/components/drilldown/views/tests/SecretDrillDown.test.tsx Removes as any from typed data prop.
web/src/components/drilldown/views/tests/ResourcesDrillDown.test.tsx Replaces {} as any with data={{}}.
web/src/components/drilldown/views/tests/ReplicaSetDrillDown.test.tsx Removes as any from typed data prop.
web/src/components/drilldown/views/tests/RBACDrillDown.test.tsx Removes as any from typed data prop.
web/src/components/drilldown/views/tests/PodDrillDown.test.tsx Removes as any from typed data prop.
web/src/components/drilldown/views/tests/NodeDrillDown.test.tsx Removes as any from typed data prop.
web/src/components/drilldown/views/tests/NamespaceDrillDown.test.tsx Removes as any from typed data prop.
web/src/components/drilldown/views/tests/MultiClusterSummaryDrillDown.test.tsx Removes as any from typed data prop.
web/src/components/drilldown/views/tests/LogsDrillDown.test.tsx Removes as any from typed data prop.
web/src/components/drilldown/views/tests/GPUNodeDrillDown.test.tsx Removes as any from typed data prop.
web/src/components/drilldown/views/tests/GPUNamespaceDrillDown.test.tsx Removes as any from typed data prop.
web/src/components/drilldown/views/tests/EventsDrillDown.test.tsx Removes as any from typed data prop.
web/src/components/drilldown/views/tests/DeploymentDrillDown.test.tsx Removes as any from typed data prop.
web/src/components/drilldown/views/tests/CostDrillDown.test.tsx Removes as any from typed data prop.
web/src/components/drilldown/views/tests/ConfigMapDrillDown.test.tsx Removes as any from typed data prop.
web/src/components/drilldown/views/tests/ComplianceDrillDown.test.tsx Removes as any from typed data prop.
web/src/components/dashboard/tests/PostConnectBanner.test.tsx Replaces {} as any with explicit props.
web/src/components/clusters/add-cluster/tests/CopyButton.test.tsx Replaces {} as any with explicit props.
web/src/components/clusters/add-cluster/tests/ConnectTab.test.tsx Replaces {} as any with explicit props.
web/src/components/clusters/tests/EmptyClusterState.test.tsx Replaces {} as any with explicit props.
web/src/components/clusters/tests/CPUDetailModal.test.tsx Replaces {} as any with explicit props.
web/src/components/cards/rss/tests/RSSFeed.test.tsx Removes {} as any render props.
web/src/components/cards/llmd/shared/tests/PortalTooltip.test.tsx Replaces {} as any with explicit props/children.
web/src/components/cards/llmd/shared/tests/HorseshoeGauge.test.tsx Replaces {} as any with explicit props.
web/src/components/cards/insights/tests/InsightSourceBadge.test.tsx Replaces {} as any with explicit props.
web/src/components/cards/deploy/tests/GitOpsDriftDetailModal.test.tsx Replaces as any with null for nullable props.
web/src/components/cards/compliance/tests/PolicyViolationDetailModal.test.tsx Replaces as any with null for nullable props.
web/src/components/cards/tests/TopPods.test.tsx Removes {} as any render props.
web/src/components/cards/tests/ServiceImports.test.tsx Removes {} as any render props.
web/src/components/cards/tests/ServiceExports.test.tsx Removes {} as any render props.
web/src/components/cards/tests/SecurityIssues.test.tsx Removes {} as any render props.
web/src/components/cards/tests/NamespaceRBAC.test.tsx Removes {} as any render props.
web/src/components/cards/tests/DeploymentIssues.test.tsx Removes {} as any render props.
web/src/components/cards/tests/CrossClusterPolicyComparison.test.tsx Removes {} as any render props.
web/src/components/cards/tests/ClusterDropZone.test.tsx Replaces {} as any with explicit props.

Comment on lines 136 to 139
export interface InstallResult {
type: MarketplaceItemType
// eslint-disable-next-line @typescript-eslint/no-explicit-any
data?: any
data?: unknown
}
Copy link

Copilot AI Apr 1, 2026

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

InstallResult is now unknown, but installItem() has a well-defined response shape per item type. Consider making InstallResult a discriminated union (e.g. card-preset/theme/dashboard) so callers can access typed fields (like dashboard cards) without Record<string, unknown> casts and runtime 'in' checks.

Copilot uses AI. Check for mistakes.
Comment on lines +632 to 636
const dashData = result.data as Record<string, unknown>
const cards = (Array.isArray(dashData.cards) ? dashData.cards : []) as unknown[]
try {
localStorage.setItem(`kubestellar-custom-dashboard-${item.id}-cards`, JSON.stringify(cards))
} catch { /* non-critical */ }
Copy link

Copilot AI Apr 1, 2026

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This code has to downcast result.data to Record<string, unknown> and treat cards as unknown[], which largely defeats the type-safety goal of the PR. The backend POST /api/dashboards/import returns a DashboardWithCards payload (includes cards), but useMarketplace.installItem() currently types that call as { id: string }, forcing these casts. Align the installItem() return type with the actual API response and then remove the Record<string, unknown> / unknown[] casts here.

Copilot uses AI. Check for mistakes.
@clubanderson
Copy link
Copy Markdown
Collaborator Author

πŸ”„ Auto-Applying Copilot Code Review

Copilot code review found 0 code suggestion(s) and 2 general comment(s).

Also address these general comments:

  • web/src/hooks/useMarketplace.ts (line 139): InstallResult is now unknown, but installItem() has a well-defined response shape per item type. Consider making `
  • web/src/components/marketplace/Marketplace.tsx (line 636): This code has to downcast result.data to Record<string, unknown> and treat cards as unknown[], which largely def

Push all fixes in a single commit. Run cd web && npm run build && npm run lint before committing.


Auto-generated by copilot-review-apply workflow.

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

Labels

dco-signoff: yes Indicates the PR's author has signed the DCO. size/L Denotes a PR that changes 100-499 lines, ignoring generated files.

Projects

None yet

Development

Successfully merging this pull request may close these issues.

3 participants