Skip to content

Conversation

@Sam-61s
Copy link
Contributor

@Sam-61s Sam-61s commented Dec 24, 2025

Description

  • Created shared RoadmapItem type definition in components/roadmap/types.ts for consistent typing across roadmap components
  • Replaced all problematic any types with proper TypeScript interfaces and types
  • Added TocSection interface to CaseTOC.tsx for table of contents data structure
  • Made Filter component generic with FilterProps<T> for improved type flexibility
  • Updated roadmap components (RoadmapColumn, RoadmapList, RoadmapItem, RoadmapPill) to use shared types
  • Improved type guards in applyFilter.ts with proper type checking instead of any

Benefits

  • Type Safety - Catches errors at compile time rather than runtime
  • Better IntelliSense - Improved IDE autocomplete and inline documentation
  • Refactoring Safety - Changes propagate errors across all usages
  • Self-Documenting Code - Types serve as inline documentation for developers

Files Changed

created
components/roadmap/types.ts

modified
components/helpers/applyFilter.ts
components/roadmap/RoadmapItem.tsx
components/roadmap/RoadmapColumn.tsx
components/roadmap/RoadmapList.tsx
components/roadmap/RoadmapPill.tsx
components/navigation/Filter.tsx
components/CaseTOC.tsx
pages/roadmap.tsx

Testing

  • npx tsc --noEmit passes with 0 errors
  • ✅ No linter errors in modified files
  • ✅ All existing functionality preserved
  • ✅ No breaking changes to component APIs

Related issue(s)

Resolves #4704

Summary by CodeRabbit

  • Improvements
    • Table of contents now preserves nested sections and indentation for clearer in-page navigation.
    • Filtering logic is more robust and consistent, preventing missing options and improving behavior.
    • Filter component and helpers use safer, generic typings to reduce runtime type issues.
    • Roadmap entries accept richer description content (React nodes) for more expressive items.
    • Public-facing prop and type definitions tightened for greater stability and consistency.

✏️ Tip: You can customize this high-level summary in your review settings.

@netlify
Copy link

netlify bot commented Dec 24, 2025

Deploy Preview for asyncapi-website ready!

Built without sensitive environment variables

Name Link
🔨 Latest commit 2867c75
🔍 Latest deploy log https://app.netlify.com/projects/asyncapi-website/deploys/695a4a9678d8bf0008245672
😎 Deploy Preview https://deploy-preview-4766--asyncapi-website.netlify.app
📱 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.

Copy link

@github-actions github-actions bot left a comment

Choose a reason for hiding this comment

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

Welcome to AsyncAPI. Thanks a lot for creating your first pull request. Please check out our contributors guide useful for opening a pull request.
Keep in mind there are also other channels you can use to interact with AsyncAPI community. For more details check out this issue.

@coderabbitai
Copy link
Contributor

coderabbitai bot commented Dec 24, 2025

📝 Walkthrough

Walkthrough

Replaced broad any types with concrete TypeScript types across components: added RoadmapItem and TocSection, made filter helpers and the Filter component generic, tightened type guards in applyFilter, and updated public prop/function signatures to use the new types (type-only changes, no runtime behavior changes). (36 words)

Changes

Cohort / File(s) Summary
Roadmap types & usages
components/roadmap/types.ts, components/roadmap/RoadmapItem.tsx, components/roadmap/RoadmapList.tsx, components/roadmap/RoadmapColumn.tsx, components/roadmap/RoadmapPill.tsx, pages/roadmap.tsx
Added exported RoadmapItem interface and switched inline/any shapes to RoadmapItem/alias across item, list, column and page; widened description to `string
Filter helpers
components/helpers/applyFilter.ts
Exported DataObject and Filter types, generic-ized applyFilterList and onFilterApply, tightened type guards and explicit handling for string vs object results; adjusted index signatures to unknown and optional name.
Filter component generics
components/navigation/Filter.tsx
Made Filter generic (T extends DataObject); FilterProps now uses T[] and onFilter: (data: T[], query: Filter) => void; refined state and effect typings and usage of onFilterApply.
Case TOC typing
components/CaseTOC.tsx
Introduced TocSection type; changed CaseTOCProps.toc and convertContentToTocItems to TocSection[]; updated logic to consume nested title/children structure and build recursive TOC items.
Blog page filter signature update
pages/blog/index.tsx
Added Filter type import and updated onFilter to accept unused _query: Filter parameter alongside filtered data.

Estimated code review effort

🎯 3 (Moderate) | ⏱️ ~25 minutes

Poem

🐇 I hopped through files both old and new,
Replaced each any with types that grew.
Roadmaps and TOCs, filters tuned with care,
Safer types now scurry everywhere.
A tiny hop — a cleaner codebase flair!

Pre-merge checks and finishing touches

✅ Passed checks (5 passed)
Check name Status Explanation
Description Check ✅ Passed Check skipped - CodeRabbit’s high-level summary is enabled.
Title check ✅ Passed The pull request title 'fix: replace TypeScript 'any' types with proper type definitions' clearly and directly describes the main change in the changeset, matching the primary objective of replacing 'any' types across multiple components.
Linked Issues check ✅ Passed The PR successfully implements all objectives from issue #4704: creates shared RoadmapItem type, removes 'any' usages, makes Filter generic, adds TocSection interface, and updates all specified files with proper type definitions.
Out of Scope Changes check ✅ Passed All changes are directly related to replacing 'any' types with proper type definitions. The modifications to pages/blog/index.tsx adding _query parameter align with the FilterProps generics improvement scope.
Docstring Coverage ✅ Passed Docstring coverage is 100.00% which is sufficient. The required threshold is 80.00%.
✨ Finishing touches
  • 📝 Generate docstrings

📜 Recent review details

Configuration used: Path: .coderabbit.yaml

Review profile: CHILL

Plan: Pro

📥 Commits

Reviewing files that changed from the base of the PR and between d2b9e71 and 2867c75.

📒 Files selected for processing (1)
  • pages/blog/index.tsx
🚧 Files skipped from review as they are similar to previous changes (1)
  • pages/blog/index.tsx
⏰ Context from checks skipped due to timeout of 180000ms. You can increase the timeout in your CodeRabbit configuration to a maximum of 15 minutes (900000ms). (4)
  • GitHub Check: Redirect rules - asyncapi-website
  • GitHub Check: Header rules - asyncapi-website
  • GitHub Check: Pages changed - asyncapi-website
  • GitHub Check: Test NodeJS PR - windows-latest

Thanks for using CodeRabbit! It's free for OSS, and your support helps us grow. If you like it, consider giving us a shout-out.

❤️ Share

Comment @coderabbitai help to get the list of available commands and usage tips.

@asyncapi-bot
Copy link
Contributor

asyncapi-bot commented Dec 24, 2025

⚡️ Lighthouse report for the changes in this PR:

Category Score
🔴 Performance 37
🟢 Accessibility 98
🟢 Best practices 92
🟢 SEO 100
🔴 PWA 33

Lighthouse ran on https://deploy-preview-4766--asyncapi-website.netlify.app/

Copy link
Contributor

@coderabbitai coderabbitai bot left a comment

Choose a reason for hiding this comment

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

Actionable comments posted: 5

🧹 Nitpick comments (1)
components/navigation/Filter.tsx (1)

26-26: Consider removing the default any to encourage explicit typing.

The default T = any maintains backward compatibility but weakens type safety guarantees. Consumers should ideally provide explicit type parameters when using this component.

📜 Review details

Configuration used: Path: .coderabbit.yaml

Review profile: CHILL

Plan: Pro

📥 Commits

Reviewing files that changed from the base of the PR and between e917b0d and ade94ab.

📒 Files selected for processing (9)
  • components/CaseTOC.tsx
  • components/helpers/applyFilter.ts
  • components/navigation/Filter.tsx
  • components/roadmap/RoadmapColumn.tsx
  • components/roadmap/RoadmapItem.tsx
  • components/roadmap/RoadmapList.tsx
  • components/roadmap/RoadmapPill.tsx
  • components/roadmap/types.ts
  • pages/roadmap.tsx
🧰 Additional context used
🧬 Code graph analysis (4)
components/roadmap/RoadmapColumn.tsx (2)
components/roadmap/RoadmapItem.tsx (1)
  • RoadmapItem (27-60)
components/roadmap/types.ts (1)
  • RoadmapItem (4-11)
components/roadmap/types.ts (1)
components/roadmap/RoadmapItem.tsx (1)
  • RoadmapItem (27-60)
components/navigation/Filter.tsx (1)
components/helpers/applyFilter.ts (2)
  • applyFilterList (42-123)
  • onFilterApply (131-163)
pages/roadmap.tsx (2)
components/roadmap/RoadmapItem.tsx (1)
  • RoadmapItem (27-60)
components/roadmap/types.ts (1)
  • RoadmapItem (4-11)
🪛 GitHub Actions: PR testing - if Node project
components/roadmap/types.ts

[error] 7-7: 'React' is not defined. (no-undef)


[error] 12-12: Delete prettier/prettier


[error] 7-7: 'React' is not defined. no-undef


[error] 12-12: Delete prettier/prettier

components/navigation/Filter.tsx

[warning] 34-34: React Hook useEffect has missing dependencies: 'checks' and 'data'.


[warning] 38-38: React Hook useEffect has missing dependencies: 'data' and 'onFilter'.

⏰ Context from checks skipped due to timeout of 180000ms. You can increase the timeout in your CodeRabbit configuration to a maximum of 15 minutes (900000ms). (4)
  • GitHub Check: Redirect rules - asyncapi-website
  • GitHub Check: Header rules - asyncapi-website
  • GitHub Check: Pages changed - asyncapi-website
  • GitHub Check: Lighthouse CI
🔇 Additional comments (7)
components/CaseTOC.tsx (1)

14-17: LGTM! Clean type safety improvement.

The introduction of the TocSection interface effectively replaces any[] with proper typing for table-of-contents data. The type definition is consistent throughout the component, improving IntelliSense and type checking without altering runtime behavior.

Also applies to: 29-29, 50-50

components/roadmap/RoadmapColumn.tsx (1)

9-9: LGTM! Proper use of shared RoadmapItem type.

The component correctly imports and uses the RoadmapItem type from the centralized types file, replacing the previous any[] typing. The type-only import is the appropriate pattern for this use case.

Also applies to: 15-15

components/roadmap/RoadmapPill.tsx (1)

32-32: LGTM! Type widening aligns with RoadmapItem interface.

Expanding the description type to accept React.ReactNode aligns with the centralized RoadmapItem type definition and enables richer content while maintaining backward compatibility. The existing render logic at line 99 already handles React nodes correctly.

pages/roadmap.tsx (1)

11-11: LGTM! RoadmapData properly typed with centralized interface.

The RoadmapData interface now uses RoadmapItem[] instead of any[] for all outcome arrays, providing proper type safety throughout the roadmap page. The type-only import is the correct pattern.

Also applies to: 19-21

components/roadmap/RoadmapList.tsx (1)

6-6: LGTM! Consistent use of centralized RoadmapItem type.

The component correctly replaces inline object typing with the imported RoadmapItemType from the shared types file. The type alias pattern maintains consistency with RoadmapItem.tsx.

Also applies to: 11-11

components/roadmap/RoadmapItem.tsx (1)

7-7: LGTM! Properly migrated to centralized type definition.

The component correctly replaces inline object typing with the imported RoadmapItemType from the shared types file. The type alias pattern maintains consistency across roadmap components.

Also applies to: 10-10

components/helpers/applyFilter.ts (1)

3-3: LGTM! Robust type guards replace unsafe any usage.

The type guards have been significantly strengthened:

  • Proper object checks using typeof x === 'object' && x !== null && 'name' in x patterns
  • Explicit string type checking with typeof x === 'string'
  • The filter logic correctly handles mixed arrays containing both objects with name properties and plain strings

The implementation correctly uses .some() for object matching and .includes() for string matching, ensuring type-safe filtering without altering runtime behavior.

Also applies to: 63-81, 94-108, 145-153

Copy link
Contributor

@coderabbitai coderabbitai bot left a comment

Choose a reason for hiding this comment

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

Actionable comments posted: 0

Caution

Some comments are outside the diff and can’t be posted inline due to platform limitations.

⚠️ Outside diff range comments (1)
components/CaseTOC.tsx (1)

143-143: Stale JSDoc: update @param {any[]} to @param {TocSection[]}.

The JSDoc still references any[] for props.toc, but the actual type is now TocSection[] (line 29).

🔎 Proposed fix
- * @param {any[]} props.toc - The table of contents data.
+ * @param {TocSection[]} props.toc - The table of contents data.
♻️ Duplicate comments (3)
components/navigation/Filter.tsx (3)

11-16: Type signature mismatch for onFilter callback.

The onFilter prop is typed as (data: T[]) => void, but onFilterApply in applyFilter.ts (line 133) expects (result: DataObject[], query: Filter) => void and calls it with two arguments. The as any cast on line 37 hides this mismatch.

🔎 Proposed fix to align the signature
 interface FilterProps<T = any> {
   data: T[];
-  onFilter: (data: T[]) => void;
+  onFilter: (data: T[], query?: Record<string, string>) => void;
   checks: Check[];
   className?: string;
 }

31-34: Missing dependencies and as any cast undermine type safety.

Pipeline warning confirms checks and data are missing from the dependency array. The data as any cast also defeats the purpose of the generic type parameter.

🔎 Proposed fix
   useEffect(() => {
     setQuery(route.query as Record<string, string>);
     applyFilterList(checks, data as any, setFilters);
-  }, [route]);
+  }, [route, checks, data]);

To fully remove the as any cast, applyFilterList would need to accept a generic type or a broader base type constraint that T satisfies.


36-38: Missing dependencies and double as any casts hide type issues.

Pipeline warning confirms data and onFilter are missing from the dependency array. The double as any casts mask the signature mismatch mentioned earlier.

🔎 Proposed fix for dependencies
   useEffect(() => {
     onFilterApply(data as any, onFilter as any, routeQuery);
-  }, [routeQuery]);
+  }, [routeQuery, data, onFilter]);

Note: Adding onFilter to dependencies may cause re-renders if the parent doesn't memoize it with useCallback. Once the onFilter signature is corrected per the earlier comment, the as any casts can be removed.

🧹 Nitpick comments (2)
components/CaseTOC.tsx (1)

50-73: Consider explicit typing to eliminate the type assertion.

The implicit array typing on line 51 and the untyped object on line 54 require the type assertion on line 66. Explicit typing would make the code cleaner.

🔎 Proposed refactor
 const convertContentToTocItems = (content: TocSection[], level: number = 1): TocItem[] => {
-  const tocItems = [];
+  const tocItems: TocItem[] = [];

   for (const section of content) {
-    const item = {
+    const item: TocItem = {
       lvl: level,
       content: section.title,
       slug: section.title
         .replace(/<|>|"|\\|\/|=/gi, '')
         .replace(/\s/gi, '-')
-        .toLowerCase()
+        .toLowerCase(),
+      children: undefined
     };

     if (section.children && section.children.length > 0) {
-      const children = convertContentToTocItems(section.children, level + 1);
-
-      (item as TocItem).children = children;
+      item.children = convertContentToTocItems(section.children, level + 1);
     }

     tocItems.push(item);
   }

   return tocItems;
 };
components/helpers/applyFilter.ts (1)

144-153: Logic is correct but consider early termination for clarity.

The approach of using .some() for object elements followed by .includes() for string elements works correctly due to the OR logic. However, the propertyValue.includes(query[property]) call on an array containing { name: string } objects will perform unnecessary comparisons.

Consider a minor refactor for efficiency and clarity:

🔎 Optional: More explicit separation of object vs string array handling
         return (
-            propertyValue.some((data) =>
-              typeof data === 'object' && data !== null && 'name' in data ? data.name === query[property] : false
-            ) ||
-            propertyValue.includes(query[property]) ||
-            false
+            propertyValue.some((data) => {
+              if (typeof data === 'object' && data !== null && 'name' in data) {
+                return data.name === query[property];
+              }
+              return data === query[property];
+            })
           );
📜 Review details

Configuration used: Path: .coderabbit.yaml

Review profile: CHILL

Plan: Pro

📥 Commits

Reviewing files that changed from the base of the PR and between ade94ab and 3eb2dac.

📒 Files selected for processing (9)
  • components/CaseTOC.tsx
  • components/helpers/applyFilter.ts
  • components/navigation/Filter.tsx
  • components/roadmap/RoadmapColumn.tsx
  • components/roadmap/RoadmapItem.tsx
  • components/roadmap/RoadmapList.tsx
  • components/roadmap/RoadmapPill.tsx
  • components/roadmap/types.ts
  • pages/roadmap.tsx
🚧 Files skipped from review as they are similar to previous changes (6)
  • components/roadmap/RoadmapPill.tsx
  • components/roadmap/RoadmapColumn.tsx
  • components/roadmap/RoadmapList.tsx
  • components/roadmap/RoadmapItem.tsx
  • components/roadmap/types.ts
  • pages/roadmap.tsx
🧰 Additional context used
🧠 Learnings (1)
📚 Learning: 2024-11-11T21:30:32.478Z
Learnt from: amanbhoria
Repo: asyncapi/website PR: 3373
File: components/AlgoliaSearch.tsx:313-313
Timestamp: 2024-11-11T21:30:32.478Z
Learning: In the `SearchButton` component within `components/AlgoliaSearch.tsx`, if the component re-renders on every button click and the `useEffect` runs accordingly, adding dependencies to the dependency array might not be necessary.

Applied to files:

  • components/navigation/Filter.tsx
🧬 Code graph analysis (1)
components/navigation/Filter.tsx (1)
components/helpers/applyFilter.ts (2)
  • applyFilterList (42-123)
  • onFilterApply (131-163)
🪛 GitHub Actions: PR testing - if Node project
components/navigation/Filter.tsx

[warning] 34-34: React Hook useEffect has missing dependencies: 'checks' and 'data'. (react-hooks/exhaustive-deps)


[warning] 38-38: React Hook useEffect has missing dependencies: 'data' and 'onFilter'. (react-hooks/exhaustive-deps)

⏰ Context from checks skipped due to timeout of 180000ms. You can increase the timeout in your CodeRabbit configuration to a maximum of 15 minutes (900000ms). (3)
  • GitHub Check: Redirect rules - asyncapi-website
  • GitHub Check: Header rules - asyncapi-website
  • GitHub Check: Pages changed - asyncapi-website
🔇 Additional comments (6)
components/CaseTOC.tsx (1)

14-17: Well-designed type replacement for TOC structure.

The TocSection interface properly models the recursive TOC structure with title and optional nested children. Replacing any[] with TocSection[] in CaseTOCProps delivers the type safety improvements outlined in the PR objectives.

Also applies to: 29-29

components/helpers/applyFilter.ts (3)

1-4: LGTM on the DataObject interface update.

The index signature now properly constrains values to string | Array<{ name: string } | string>, which aligns with how the data is actually used in the filter functions. The name: string property is compatible since string is part of the union.


61-91: Type guards are well-implemented.

The combination of typeof a === 'object' && a !== null && 'name' in a correctly narrows the type. The separate handling of string elements in lines 73-81 and 83-91 ensures all cases are covered.


92-117: Consistent type handling in the initialization branch.

The else branch mirrors the type-checking logic correctly, ensuring both object-with-name and plain string elements are handled during initial list population.

components/navigation/Filter.tsx (2)

26-29: Good use of generics and typed state.

The generic component signature Filter<T = any> and the explicit state types for filters and routeQuery improve type clarity over the previous implementation.


40-84: Render logic is sound.

The Select component rendering, query parameter management, and shallow routing are implemented correctly. No issues with this portion.

Copy link
Contributor

@coderabbitai coderabbitai bot left a comment

Choose a reason for hiding this comment

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

Actionable comments posted: 1

♻️ Duplicate comments (2)
components/navigation/Filter.tsx (2)

11-16: Signature mismatch: onFilter prop still doesn't match onFilterApply expectations.

The onFilter prop is typed as (data: T[]) => void, but the onFilterApply helper (line 37) calls it with two arguments: onFilter(result, query). This mismatch remains unresolved from the previous review and is currently masked by the as any cast on line 37.

🔎 Recommended fix

Update the FilterProps interface to match what onFilterApply actually calls:

 interface FilterProps<T = any> {
   data: T[];
-  onFilter: (data: T[]) => void;
+  onFilter: (data: T[], query: Record<string, string>) => void;
   checks: Check[];
   className?: string;
 }

Then remove the as any cast on line 37.


36-38: Good: Dependencies added, but double as any casts hide fundamental type mismatches.

✅ The dependency array now correctly includes routeQuery, data, and onFilter.

❌ However, both data as any and onFilter as any casts on line 37 mask underlying type incompatibilities:

  1. Data type: onFilterApply expects DataObject[] but receives T[]
  2. Callback signature: onFilterApply expects onFilter: (result: DataObject[], query: Filter) => void but the prop is typed as (data: T[]) => void (see comment on lines 11-16)

Both issues must be resolved to safely remove these casts and achieve the PR's goal of eliminating any types.

🔎 Recommended approach
  1. Fix the onFilter signature per the comment on lines 11-16
  2. Either constrain T extends DataObject or make the helper functions generic
  3. Remove both as any casts once types align
📜 Review details

Configuration used: Path: .coderabbit.yaml

Review profile: CHILL

Plan: Pro

📥 Commits

Reviewing files that changed from the base of the PR and between 3eb2dac and c972a34.

📒 Files selected for processing (2)
  • components/navigation/Filter.tsx
  • components/roadmap/types.ts
🚧 Files skipped from review as they are similar to previous changes (1)
  • components/roadmap/types.ts
🧰 Additional context used
🧠 Learnings (1)
📚 Learning: 2024-11-11T21:30:32.478Z
Learnt from: amanbhoria
Repo: asyncapi/website PR: 3373
File: components/AlgoliaSearch.tsx:313-313
Timestamp: 2024-11-11T21:30:32.478Z
Learning: In the `SearchButton` component within `components/AlgoliaSearch.tsx`, if the component re-renders on every button click and the `useEffect` runs accordingly, adding dependencies to the dependency array might not be necessary.

Applied to files:

  • components/navigation/Filter.tsx
🧬 Code graph analysis (1)
components/navigation/Filter.tsx (1)
components/helpers/applyFilter.ts (2)
  • applyFilterList (42-123)
  • onFilterApply (131-163)

@codecov
Copy link

codecov bot commented Dec 24, 2025

Codecov Report

✅ All modified and coverable lines are covered by tests.
✅ Project coverage is 100.00%. Comparing base (18ec38f) to head (2867c75).
⚠️ Report is 1 commits behind head on master.

Additional details and impacted files
@@            Coverage Diff            @@
##            master     #4766   +/-   ##
=========================================
  Coverage   100.00%   100.00%           
=========================================
  Files           22        22           
  Lines          798       798           
  Branches       146       146           
=========================================
  Hits           798       798           

☔ View full report in Codecov by Sentry.
📢 Have feedback on the report? Share it here.

🚀 New features to boost your workflow:
  • ❄️ Test Analytics: Detect flaky tests, report on failures, and find test suite problems.
  • 📦 JS Bundle Analysis: Save yourself from yourself by tracking and limiting bundle sizes in JS merges.

@princerajpoot20
Copy link
Member

@Sam-61s have a look at the coderabbit suggestion

@Sam-61s
Copy link
Contributor Author

Sam-61s commented Jan 2, 2026

I think, I’ve addressed all the CodeRabbitAI review comments and updated the PR accordingly.
Could you please take another look?

@princerajpoot20
Copy link
Member

/rtm

@asyncapi-bot asyncapi-bot merged commit 90e4b00 into asyncapi:master Jan 4, 2026
22 checks passed
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Projects

None yet

Development

Successfully merging this pull request may close these issues.

[Fix]: replace TypeScript 'any' types with proper type definitions

3 participants