Skip to content

More undefined checks#6747

Merged
ckifer merged 4 commits intomainfrom
ts-strict
Dec 7, 2025
Merged

More undefined checks#6747
ckifer merged 4 commits intomainfrom
ts-strict

Conversation

@PavelVanecek
Copy link
Collaborator

@PavelVanecek PavelVanecek commented Dec 6, 2025

Related Issue

#6645

Summary by CodeRabbit

  • Bug Fixes

    • Improved handling of missing or undefined data points in charts to prevent rendering errors
    • Enhanced null safety checks in animation and calculation functions
    • Better error handling and fallback behavior for malformed CSS and unit values
  • Refactor

    • Strengthened type safety, input validation, and error guards throughout animation and charting systems for more reliable rendering

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

@coderabbitai
Copy link
Contributor

coderabbitai bot commented Dec 6, 2025

Walkthrough

The PR refactors type safety and null-checking across the codebase. Key changes include renaming getEveryNthWithCondition to getEveryNth, removing generics from CSSTransitionAnimate, introducing generic constraints to ErrorBarDataPointFormatter and ErrorBarContextType, and adding defensive null guards and optional chaining throughout animation, cartesian, and utility modules.

Changes

Cohort / File(s) Summary
Snapshot file updates
scripts/snapshots/es6Files.txt, scripts/snapshots/libFiles.txt, scripts/snapshots/typesFiles.txt
Snapshot manifests updated to replace references to getEveryNthWithCondition with getEveryNth.
Function rename and null safety
src/util/getEveryNth.ts, src/util/TickUtils.ts, src/cartesian/getEquidistantTicks.ts
getEveryNthWithCondition renamed to getEveryNth with added undefined-element guard. Callsites updated to use new function name.
CSSTransitionAnimate refactoring
src/animation/CSSTransitionAnimate.tsx
Removed generic type parameter T; changed from and to props from T to string; updated function signature and state initialization from generic to concrete ReactSmoothStyle type.
ErrorBar generic and null-safety enhancements
src/cartesian/ErrorBar.tsx, src/cartesian/Bar.tsx, src/cartesian/Line.tsx, src/cartesian/Scatter.tsx
Made ErrorBarDataPointFormatter generic with type parameter T; specialized implementations in Bar/Line/Scatter; added null checks for array error values in ErrorBar; strengthened typing in Bar.
ErrorBarContext type constraints
src/context/ErrorBarContext.tsx
Added generic constraints to ErrorBarContextType and SetErrorBarContext requiring T extends BarRectangleItem | LinePointItem | ScatterPointItem; updated dataPointFormatter to use generic ErrorBarDataPointFormatter<T>.
Animation null safety
src/animation/AnimationManager.ts, src/animation/configUpdate.ts, src/animation/easing.ts
Widened type to allow undefined parameter in setStyle; added null-check guards in configUpdate reduce operations; extracted parseCubicBezier helper in easing.ts.
Cartesian null safety
src/cartesian/Area.tsx
Replaced direct point property access with optional chaining (points[0]?.y, etc.); introduced value1 variable and refactored breakpoint value derivation.
Type safety improvements in utilities
src/util/ReduceCSSCalc.ts
Introduced SupportedUnits type; changed CONVERSION_RATES from Record<string, number> to Record<SupportedUnits, number>; added isSupportedUnit type guard; updated convertToPx and calculateArithmetic signatures; added DecimalCSS.NaN static member and enhanced parse error handling.
Utility type and null guard enhancements
src/util/DataUtils.ts, src/util/isDomainSpecifiedByUser.ts, src/util/scale/getNiceTickValues.ts
Added optional chaining for cx/cy in getLinearRegression; added null check on regex capture group in isDomainSpecifiedByUser; added explicit return type annotation to getValidInterval.

Estimated code review effort

🎯 4 (Complex) | ⏱️ ~45 minutes

  • CSSTransitionAnimate.tsx: Generic removal affects public API; verify all consumers handle non-generic prop types and string-only from/to.
  • ErrorBar-related changes (ErrorBar.tsx, ErrorBarContext.tsx, Bar.tsx, Line.tsx, Scatter.tsx): Generic constraint introduction across multiple cartesian components requires careful verification of type flow and compatibility at call sites.
  • Logic changes with null guards: Review null checks in configUpdate.ts, ErrorBar.tsx, and Area.tsx to ensure they handle edge cases correctly and don't mask legitimate issues.
  • ReduceCSSCalc.ts: Type narrowing with SupportedUnits and isSupportedUnit guard; verify no valid units are excluded and NaN propagation is correct.

Possibly related PRs

Suggested labels

typescript

Suggested reviewers

  • ckifer

Pre-merge checks and finishing touches

❌ Failed checks (2 warnings, 1 inconclusive)
Check name Status Explanation Resolution
Description check ⚠️ Warning The PR description is largely incomplete, providing only a related issue link without fulfilling required template sections such as motivation, testing details, type of change, and verification checklist. Complete the PR description by filling out the template sections: explain the motivation and context, describe how the changes were tested, specify the type of change, and complete the verification checklist.
Docstring Coverage ⚠️ Warning Docstring coverage is 10.00% which is insufficient. The required threshold is 80.00%. You can run @coderabbitai generate docstrings to improve docstring coverage.
Title check ❓ Inconclusive The title 'More undefined checks' is vague and generic, using non-descriptive language that doesn't convey what specific changes were made or which parts of the codebase were modified. Consider a more specific title that describes the main change, such as 'Add undefined safety checks across animation and utility modules' or 'Refactor getEveryNthWithCondition to getEveryNth with additional null guards'.
✨ Finishing touches
  • 📝 Generate docstrings
🧪 Generate unit tests (beta)
  • Create PR with unit tests
  • Post copyable unit tests in a comment
  • Commit unit tests in branch ts-strict

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.

@codecov
Copy link

codecov bot commented Dec 6, 2025

Codecov Report

❌ Patch coverage is 91.66667% with 7 lines in your changes missing coverage. Please review.
✅ Project coverage is 93.95%. Comparing base (0c77f1c) to head (2d01757).
⚠️ Report is 6 commits behind head on main.

Files with missing lines Patch % Lines
src/animation/configUpdate.ts 83.33% 2 Missing ⚠️
src/cartesian/Bar.tsx 66.66% 2 Missing ⚠️
src/cartesian/ErrorBar.tsx 71.42% 2 Missing ⚠️
src/animation/easing.ts 93.33% 1 Missing ⚠️
Additional details and impacted files
@@            Coverage Diff             @@
##             main    #6747      +/-   ##
==========================================
- Coverage   93.96%   93.95%   -0.02%     
==========================================
  Files         504      504              
  Lines       42177    42211      +34     
  Branches     4925     4939      +14     
==========================================
+ Hits        39633    39660      +27     
- Misses       2539     2546       +7     
  Partials        5        5              

☔ 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.

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

Caution

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

⚠️ Outside diff range comments (1)
src/util/ReduceCSSCalc.ts (1)

8-24: Avoid as in isSupportedUnit per TypeScript guidelines

The new SupportedUnits typing and restricted convertToPx signature are good, but isSupportedUnit currently relies on a unit as SupportedUnits assertion, which conflicts with the “no as (except as const)" guideline for *.ts files.

You can keep the same runtime behavior and drop the assertion by using an explicit switch:

-type SupportedUnits = 'cm' | 'mm' | 'pt' | 'pc' | 'in' | 'Q' | 'px';
-
-const FIXED_CSS_LENGTH_UNITS: ReadonlyArray<SupportedUnits> = ['cm', 'mm', 'pt', 'pc', 'in', 'Q', 'px'];
-
-function isSupportedUnit(unit: string): unit is SupportedUnits {
-  return FIXED_CSS_LENGTH_UNITS.includes(unit as SupportedUnits);
-}
+type SupportedUnits = 'cm' | 'mm' | 'pt' | 'pc' | 'in' | 'Q' | 'px';
+
+const FIXED_CSS_LENGTH_UNITS: ReadonlyArray<SupportedUnits> = ['cm', 'mm', 'pt', 'pc', 'in', 'Q', 'px'];
+
+function isSupportedUnit(unit: string): unit is SupportedUnits {
+  switch (unit) {
+    case 'cm':
+    case 'mm':
+    case 'pt':
+    case 'pc':
+    case 'in':
+    case 'Q':
+    case 'px':
+      return true;
+    default:
+      return false;
+  }
+}

This keeps the unit narrowing without any non‑as const assertions, so it should satisfy the repo’s TypeScript rules.

Also applies to: 28-30, 61-64

🧹 Nitpick comments (1)
src/context/ErrorBarContext.tsx (1)

12-18: Consider using ReadonlyArray<T> instead of ReadonlyArray<any> for stronger type safety.

The generic constraint on ErrorBarContextType<T> is a good improvement. However, data: ReadonlyArray<any> loses the type information that the generic parameter provides. As per coding guidelines, any should be avoided.

While React Context has limitations with generics (the context value type is fixed at creation time), you could still type data as ReadonlyArray<T> to maintain type safety within the generic function scope:

 type ErrorBarContextType<T extends BarRectangleItem | LinePointItem | ScatterPointItem> = {
-  data: ReadonlyArray<any> | undefined;
+  data: ReadonlyArray<T> | undefined;
   xAxisId: AxisId;
   yAxisId: AxisId;
   dataPointFormatter: ErrorBarDataPointFormatter<T>;
   errorBarOffset: number;
 };

This would ensure that when SetErrorBarContext is called with a specific type, the data prop must match that type.

📜 Review details

Configuration used: CodeRabbit UI

Review profile: CHILL

Plan: Pro

📥 Commits

Reviewing files that changed from the base of the PR and between 0c77f1c and 2d01757.

📒 Files selected for processing (20)
  • scripts/snapshots/es6Files.txt (1 hunks)
  • scripts/snapshots/libFiles.txt (1 hunks)
  • scripts/snapshots/typesFiles.txt (1 hunks)
  • src/animation/AnimationManager.ts (1 hunks)
  • src/animation/CSSTransitionAnimate.tsx (3 hunks)
  • src/animation/configUpdate.ts (3 hunks)
  • src/animation/easing.ts (2 hunks)
  • src/cartesian/Area.tsx (3 hunks)
  • src/cartesian/Bar.tsx (2 hunks)
  • src/cartesian/ErrorBar.tsx (2 hunks)
  • src/cartesian/Line.tsx (1 hunks)
  • src/cartesian/Scatter.tsx (2 hunks)
  • src/cartesian/getEquidistantTicks.ts (2 hunks)
  • src/context/ErrorBarContext.tsx (2 hunks)
  • src/util/DataUtils.ts (1 hunks)
  • src/util/ReduceCSSCalc.ts (4 hunks)
  • src/util/TickUtils.ts (2 hunks)
  • src/util/getEveryNth.ts (2 hunks)
  • src/util/isDomainSpecifiedByUser.ts (2 hunks)
  • src/util/scale/getNiceTickValues.ts (1 hunks)
🧰 Additional context used
📓 Path-based instructions (4)
**/*.{ts,tsx}

📄 CodeRabbit inference engine (CONTRIBUTING.md)

**/*.{ts,tsx}: Never use any type (implicit or explicit) in TypeScript code
Prefer unknown over any and refine the type in TypeScript
Type function parameters and return values explicitly in TypeScript, do not rely on implicit any or inference; exceptions are React components and trivial functions
Do not use as type assertions in TypeScript; the only exception is as const

Files:

  • src/util/isDomainSpecifiedByUser.ts
  • src/cartesian/Line.tsx
  • src/util/scale/getNiceTickValues.ts
  • src/cartesian/Area.tsx
  • src/util/getEveryNth.ts
  • src/cartesian/Bar.tsx
  • src/cartesian/Scatter.tsx
  • src/cartesian/getEquidistantTicks.ts
  • src/animation/CSSTransitionAnimate.tsx
  • src/context/ErrorBarContext.tsx
  • src/cartesian/ErrorBar.tsx
  • src/util/TickUtils.ts
  • src/animation/configUpdate.ts
  • src/util/DataUtils.ts
  • src/animation/easing.ts
  • src/animation/AnimationManager.ts
  • src/util/ReduceCSSCalc.ts
**/*.{js,ts,tsx}

📄 CodeRabbit inference engine (CONTRIBUTING.md)

Ensure code lints by running npm run lint and follows Airbnb's Style Guide

Files:

  • src/util/isDomainSpecifiedByUser.ts
  • src/cartesian/Line.tsx
  • src/util/scale/getNiceTickValues.ts
  • src/cartesian/Area.tsx
  • src/util/getEveryNth.ts
  • src/cartesian/Bar.tsx
  • src/cartesian/Scatter.tsx
  • src/cartesian/getEquidistantTicks.ts
  • src/animation/CSSTransitionAnimate.tsx
  • src/context/ErrorBarContext.tsx
  • src/cartesian/ErrorBar.tsx
  • src/util/TickUtils.ts
  • src/animation/configUpdate.ts
  • src/util/DataUtils.ts
  • src/animation/easing.ts
  • src/animation/AnimationManager.ts
  • src/util/ReduceCSSCalc.ts
src/**/*.{ts,tsx}

📄 CodeRabbit inference engine (AGENTS.md)

Do not hardcode any strings or formatting choices in library code; users should provide localized strings as desired

Files:

  • src/util/isDomainSpecifiedByUser.ts
  • src/cartesian/Line.tsx
  • src/util/scale/getNiceTickValues.ts
  • src/cartesian/Area.tsx
  • src/util/getEveryNth.ts
  • src/cartesian/Bar.tsx
  • src/cartesian/Scatter.tsx
  • src/cartesian/getEquidistantTicks.ts
  • src/animation/CSSTransitionAnimate.tsx
  • src/context/ErrorBarContext.tsx
  • src/cartesian/ErrorBar.tsx
  • src/util/TickUtils.ts
  • src/animation/configUpdate.ts
  • src/util/DataUtils.ts
  • src/animation/easing.ts
  • src/animation/AnimationManager.ts
  • src/util/ReduceCSSCalc.ts
**/*.{ts,tsx,js,jsx}

📄 CodeRabbit inference engine (DEVELOPING.md)

All imports from recharts must use the public API entry point; imports from internal paths like recharts/types/* or recharts/src/* are not allowed

Files:

  • src/util/isDomainSpecifiedByUser.ts
  • src/cartesian/Line.tsx
  • src/util/scale/getNiceTickValues.ts
  • src/cartesian/Area.tsx
  • src/util/getEveryNth.ts
  • src/cartesian/Bar.tsx
  • src/cartesian/Scatter.tsx
  • src/cartesian/getEquidistantTicks.ts
  • src/animation/CSSTransitionAnimate.tsx
  • src/context/ErrorBarContext.tsx
  • src/cartesian/ErrorBar.tsx
  • src/util/TickUtils.ts
  • src/animation/configUpdate.ts
  • src/util/DataUtils.ts
  • src/animation/easing.ts
  • src/animation/AnimationManager.ts
  • src/util/ReduceCSSCalc.ts
🧠 Learnings (4)
📓 Common learnings
Learnt from: PavelVanecek
Repo: recharts/recharts PR: 6669
File: www/src/docs/exampleComponents/ScatterChart/ScatterChartWithLabels.tsx:2-2
Timestamp: 2025-11-23T13:30:10.395Z
Learning: The `TooltipIndex` type from recharts is defined in `src/state/tooltipSlice.ts` but is not currently exported from the public API entry points. It should not be imported from `recharts/types/state/tooltipSlice` as this is an internal implementation path. An ESLint rule is needed to prevent regressions.
📚 Learning: 2025-12-06T03:36:59.360Z
Learnt from: CR
Repo: recharts/recharts PR: 0
File: DEVELOPING.md:0-0
Timestamp: 2025-12-06T03:36:59.360Z
Learning: Applies to **/*.{ts,tsx,js,jsx} : All imports from `recharts` must use the public API entry point; imports from internal paths like `recharts/types/*` or `recharts/src/*` are not allowed

Applied to files:

  • src/cartesian/Scatter.tsx
  • scripts/snapshots/typesFiles.txt
📚 Learning: 2025-11-25T01:22:59.729Z
Learnt from: CR
Repo: recharts/recharts PR: 0
File: CONTRIBUTING.md:0-0
Timestamp: 2025-11-25T01:22:59.729Z
Learning: Applies to **/*.{ts,tsx} : Type function parameters and return values explicitly in TypeScript, do not rely on implicit any or inference; exceptions are React components and trivial functions

Applied to files:

  • src/animation/CSSTransitionAnimate.tsx
📚 Learning: 2025-11-23T13:30:10.395Z
Learnt from: PavelVanecek
Repo: recharts/recharts PR: 6669
File: www/src/docs/exampleComponents/ScatterChart/ScatterChartWithLabels.tsx:2-2
Timestamp: 2025-11-23T13:30:10.395Z
Learning: The `TooltipIndex` type from recharts is defined in `src/state/tooltipSlice.ts` but is not currently exported from the public API entry points. It should not be imported from `recharts/types/state/tooltipSlice` as this is an internal implementation path. An ESLint rule is needed to prevent regressions.

Applied to files:

  • scripts/snapshots/typesFiles.txt
🧬 Code graph analysis (9)
src/cartesian/Line.tsx (1)
src/cartesian/ErrorBar.tsx (1)
  • ErrorBarDataPointFormatter (38-42)
src/cartesian/Area.tsx (1)
src/util/ChartUtils.ts (2)
  • getValueByDataKey (41-55)
  • getCateCoordinateOfLine (470-509)
src/cartesian/Bar.tsx (3)
src/cartesian/ErrorBar.tsx (1)
  • ErrorBarDataPointFormatter (38-42)
src/index.ts (1)
  • BarRectangleItem (86-86)
src/util/ChartUtils.ts (1)
  • truncateByDomain (297-326)
src/cartesian/Scatter.tsx (1)
src/cartesian/ErrorBar.tsx (1)
  • ErrorBarDataPointFormatter (38-42)
src/cartesian/getEquidistantTicks.ts (1)
src/util/getEveryNth.ts (1)
  • getEveryNth (12-27)
src/animation/CSSTransitionAnimate.tsx (1)
src/animation/AnimationManager.ts (2)
  • AnimationManager (21-26)
  • ReactSmoothStyle (4-4)
src/context/ErrorBarContext.tsx (5)
src/cartesian/Bar.tsx (1)
  • BarRectangleItem (95-111)
src/cartesian/Line.tsx (1)
  • LinePointItem (69-78)
src/cartesian/Scatter.tsx (1)
  • ScatterPointItem (91-126)
src/state/cartesianAxisSlice.ts (1)
  • AxisId (8-8)
src/cartesian/ErrorBar.tsx (1)
  • ErrorBarDataPointFormatter (38-42)
src/cartesian/ErrorBar.tsx (3)
src/cartesian/Bar.tsx (1)
  • BarRectangleItem (95-111)
src/cartesian/Line.tsx (1)
  • LinePointItem (69-78)
src/cartesian/Scatter.tsx (1)
  • ScatterPointItem (91-126)
src/util/TickUtils.ts (1)
src/util/getEveryNth.ts (1)
  • getEveryNth (12-27)
⏰ Context from checks skipped due to timeout of 90000ms. You can increase the timeout in your CodeRabbit configuration to a maximum of 15 minutes (900000ms). (2)
  • GitHub Check: Build, Test, Pack
  • GitHub Check: Analyze (javascript-typescript)
🔇 Additional comments (30)
src/animation/AnimationManager.ts (1)

34-34: LGTM: Defensive parameter typing

Widening the parameter type to include undefined is safe. When undefined is passed, none of the type-specific branches (array, string, object, function) will match, resulting in a no-op. This makes the function more resilient to edge cases.

src/animation/easing.ts (1)

59-62: LGTM: Proper null handling with fallback

The use of parseCubicBezier with null-checking and fallback to the linear easing default (line 73) is correct. Once the NaN validation is added to parseCubicBezier, this will be fully robust.

src/animation/configUpdate.ts (3)

34-34: LGTM: Defensive guard prevents undefined access

The additional nextStepVals[key] != null check ensures that nextStepVals[key].velocity and nextStepVals[key].from are safely accessed only when the key exists. This prevents potential runtime errors in edge cases.


70-80: LGTM: Explicit type annotation improves clarity

Adding the explicit Record<string, Val> type annotation to stepperStyle enhances type safety and makes the intent clearer without changing runtime behavior.


132-142: LGTM: Robust null handling in timing style construction

The null checks for from[key] and to[key] (line 135) ensure that only valid numeric pairs are included in timingStyle. This prevents downstream errors when keys are missing or have undefined values. The as const assertion on line 140 is appropriate and follows TypeScript best practices.

src/util/isDomainSpecifiedByUser.ts (1)

151-157: Regex match-group null checks improve safety without changing behavior

The added guards match == null || match[1] == null || dataDomain == null before using match[1] in both MIN and MAX branches correctly avoid computing with an undefined capture group (which would yield NaN) and make the invalid-pattern path explicit. For malformed "dataMin/Max ± offset" strings you still end up with an invalid candidate that fails isWellFormedNumberDomain, so runtime behavior (falling back to deriving the domain from data) is preserved while improving type-safety and clarity.

Also applies to: 176-183

src/animation/CSSTransitionAnimate.tsx (3)

34-36: LGTM on the type simplification.

The as const satisfies Partial<CSSTransitionAnimateProps> pattern correctly infers literal types for defaults while ensuring type safety. The non-generic function signature aligns with the simplified props type.


56-61: State type is intentionally wider than props.

The state is typed as ReactSmoothStyle (string | object) while from/to are string. This is correct because the animation manager's subscribe callback can set intermediate animation values typed as ReactSmoothStyle. The initialization with from/to (strings) is type-safe since string is a subtype of ReactSmoothStyle.


10-24: All callers already pass string values for from and to—no breaking changes in the current codebase.

The narrowing of from/to from generic <T extends ReactSmoothStyle> to string is intentional and doesn't break any existing usages. Treemap, ErrorBar, and all tests pass string values, confirming the API change is compatible with current code. The useState<ReactSmoothStyle> correctly allows the animation manager's callback to pass both string and object values internally.

src/util/DataUtils.ts (1)

140-161: Optional chaining in getLinearRegression safely handles sparse data

Using data[i]?.cx || 0 / data[i]?.cy || 0 avoids runtime errors if data[i] is missing while preserving the “default to 0 when cx/cy are undefined” behavior. Looks good and consistent with the existing aggregation logic.

src/util/ReduceCSSCalc.ts (1)

32-44: NaN/undefined guarding in DecimalCSS.parse and calculateArithmetic looks solid

Returning DecimalCSS.NaN when NUM_SPLIT_REGEX fails (numStr == null) and short‑circuiting calculateArithmetic for expr == null or containing STR_NAN makes the arithmetic path safer against malformed input while preserving existing behavior for valid expressions. The DecimalCSS.NaN singleton is only used as a sentinel and isn’t mutated by the arithmetic methods, so this change looks safe.

Also applies to: 108-110

src/cartesian/getEquidistantTicks.ts (1)

3-3: Switch to getEveryNth keeps tick selection behavior and adds robustness

Using getEveryNth(ticks, stepsize) in the break condition preserves the “take every Nth tick” semantics while allowing the util to safely skip any undefined entries (e.g. sparse arrays). This is consistent with the new getEveryNth helper and looks correct for the getEquidistantTicks usage.

Also applies to: 27-32

src/cartesian/Scatter.tsx (1)

23-24: Scatter error bar formatter is correctly specialized to ScatterPointItem

Typing errorBarDataPointFormatter as ErrorBarDataPointFormatter<ScatterPointItem> and wiring it into SetErrorBarContext aligns Scatter with the new generic error‑bar API. Using cx/cy for coordinates, direction to pick between node.x and node.y, and getValueByDataKey(dataPoint, dataKey) matches how computeScatterPoints shapes ScatterPointItem, so the implementation looks consistent and sound.

Also applies to: 657-669, 688-693

scripts/snapshots/libFiles.txt (1)

193-224: Snapshot entry updated to match getEveryNth rename

The lib snapshot now references lib/util/getEveryNth.js, which matches the renamed util implementation and keeps the manifest in sync with the codebase.

src/util/getEveryNth.ts (1)

12-27: getEveryNth implementation matches docs and safely skips sparse entries

The new getEveryNth correctly:

  • returns [] for n < 1,
  • returns the original array for n === 1,
  • and otherwise takes indices 0, n, 2n, … up to array.length.

Guarding with item !== undefined means sparse arrays don’t produce undefined elements, which is a safe improvement. The ReadonlyArray return type is also appropriate for a utility that doesn’t promise mutability of its result.

scripts/snapshots/typesFiles.txt (1)

193-224: Types snapshot updated to reference getEveryNth typings

Referencing types/util/getEveryNth.d.ts keeps the type snapshot aligned with the renamed util and its new signature.

src/cartesian/Line.tsx (1)

24-25: Line error bar formatter correctly bound to LinePointItem

Annotating errorBarDataPointFormatter as ErrorBarDataPointFormatter<LinePointItem> cleanly ties the formatter to the line point shape while reusing the existing logic for coordinates, value, and errorVal. Its use in SetErrorBarContext remains consistent, so this is a straightforward typing improvement.

Also applies to: 630-641, 678-683

scripts/snapshots/es6Files.txt (1)

223-223: LGTM!

The snapshot correctly reflects the rename from getEveryNthWithCondition to getEveryNth.

src/util/TickUtils.ts (2)

1-3: LGTM!

Import updated to reflect the function rename from getEveryNthWithCondition to getEveryNth.


44-49: LGTM!

The function call correctly uses the renamed getEveryNth while preserving the same argument pattern (interval + 1).

src/util/scale/getNiceTickValues.ts (1)

18-27: LGTM!

The explicit return type annotation [number, number] improves type safety and aligns with TypeScript best practices. As per coding guidelines, explicit return types are preferred.

src/cartesian/Bar.tsx (2)

778-794: LGTM!

The explicit generic type ErrorBarDataPointFormatter<BarRectangleItem> aligns with the updated type signature in ErrorBar.tsx and improves type safety.


944-950: LGTM!

Good defensive null guard. Accessing stackedData[index + dataStartIndex] could return undefined if the index is out of bounds. This check prevents passing undefined to truncateByDomain and correctly returns null to filter out invalid entries.

src/cartesian/Area.tsx (3)

459-463: LGTM!

Optional chaining on points[0] and points[points.length - 1] prevents potential runtime errors when the points array is empty. The existing isWellBehavedNumber checks properly handle the resulting undefined values.


498-502: LGTM!

Same defensive optional chaining pattern applied consistently to HorizontalRect, matching the fix in VerticalRect.


980-998: LGTM!

Good null safety improvement. Extracting value1 with value?.[1] ?? null handles cases where:

  1. value is null/undefined (e.g., missing data)
  2. value[1] is undefined

This prevents runtime errors when passing potentially undefined values to yAxis.scale() or xAxis.scale().

src/cartesian/ErrorBar.tsx (2)

38-42: Good type safety improvement with the generic constraint.

The generic parameter with the union constraint properly specializes the formatter for each chart type (Bar, Line, Scatter). This enables better type inference at call sites while maintaining the flexibility needed across different chart components.


137-148: Solid defensive null handling for error bar values.

The explicit null checks for the destructured array elements prevent potential runtime issues when errorVal contains null/undefined values. This properly handles the case where the data source might have incomplete error bar data.

src/context/ErrorBarContext.tsx (2)

8-10: Imports support the new generic constraint.

These imports enable the type constraint definition and ensure consistency with the types used in the cartesian components.


30-32: Generic function signature properly constrains the context type.

The generic constraint ensures type safety when setting up the error bar context for different chart types, and correctly propagates the constraint to the props.

Comment on lines +32 to +43
const parseCubicBezier = (easing: string): [number, number, number, number] | null => {
const easingParts = easing.split('(');
if (easingParts.length !== 2 || easingParts[0] !== 'cubic-bezier') {
return null;
}
const numbers = easingParts[1]?.split(')')[0]?.split(',');
if (numbers == null || numbers.length !== 4) {
return null;
}
const coords = numbers.map((x: string) => parseFloat(x));
return [coords[0]!, coords[1]!, coords[2]!, coords[3]!];
};
Copy link
Contributor

Choose a reason for hiding this comment

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

⚠️ Potential issue | 🟠 Major

Add validation for NaN values from parseFloat

The parseCubicBezier helper doesn't validate that parseFloat produces valid numbers. Invalid numeric strings (e.g., "cubic-bezier(a,b,c,d)") will result in NaN values that propagate through calculations, potentially causing subtle animation bugs.

Apply this diff to validate the parsed coordinates:

 const parseCubicBezier = (easing: string): [number, number, number, number] | null => {
   const easingParts = easing.split('(');
   if (easingParts.length !== 2 || easingParts[0] !== 'cubic-bezier') {
     return null;
   }
   const numbers = easingParts[1]?.split(')')[0]?.split(',');
   if (numbers == null || numbers.length !== 4) {
     return null;
   }
   const coords = numbers.map((x: string) => parseFloat(x));
+  if (coords.some((coord) => Number.isNaN(coord))) {
+    return null;
+  }
   return [coords[0]!, coords[1]!, coords[2]!, coords[3]!];
 };
📝 Committable suggestion

‼️ IMPORTANT
Carefully review the code before committing. Ensure that it accurately replaces the highlighted code, contains no missing lines, and has no issues with indentation. Thoroughly test & benchmark the code to ensure it meets the requirements.

Suggested change
const parseCubicBezier = (easing: string): [number, number, number, number] | null => {
const easingParts = easing.split('(');
if (easingParts.length !== 2 || easingParts[0] !== 'cubic-bezier') {
return null;
}
const numbers = easingParts[1]?.split(')')[0]?.split(',');
if (numbers == null || numbers.length !== 4) {
return null;
}
const coords = numbers.map((x: string) => parseFloat(x));
return [coords[0]!, coords[1]!, coords[2]!, coords[3]!];
};
const parseCubicBezier = (easing: string): [number, number, number, number] | null => {
const easingParts = easing.split('(');
if (easingParts.length !== 2 || easingParts[0] !== 'cubic-bezier') {
return null;
}
const numbers = easingParts[1]?.split(')')[0]?.split(',');
if (numbers == null || numbers.length !== 4) {
return null;
}
const coords = numbers.map((x: string) => parseFloat(x));
if (coords.some((coord) => Number.isNaN(coord))) {
return null;
}
return [coords[0]!, coords[1]!, coords[2]!, coords[3]!];
};
🤖 Prompt for AI Agents
In src/animation/easing.ts around lines 32 to 43, parseCubicBezier currently
maps the four string parts directly to parseFloat without validating them;
update the function to trim each string, parse them to numbers, and verify all
four results are valid finite numbers (e.g., using Number.isFinite or
!Number.isNaN) and return null if any are invalid, preserving the existing null
returns for malformed inputs.

@codecov
Copy link

codecov bot commented Dec 6, 2025

Bundle Report

Changes will increase total bundle size by 5.47kB (0.21%) ⬆️. This is within the configured threshold ✅

Detailed changes
Bundle name Size Change
recharts/bundle-cjs 1.15MB 2.16kB (0.19%) ⬆️
recharts/bundle-es6 992.9kB 2.22kB (0.22%) ⬆️
recharts/bundle-umd 517.16kB 1.09kB (0.21%) ⬆️

Affected Assets, Files, and Routes:

view changes for bundle: recharts/bundle-es6

Assets Changed:

Asset Name Size Change Total Size Change (%)
cartesian/Area.js 477 bytes 26.52kB 1.83%
cartesian/Bar.js 114 bytes 25.48kB 0.45%
cartesian/ErrorBar.js 110 bytes 9.24kB 1.21%
util/isDomainSpecifiedByUser.js 41 bytes 7.12kB 0.58%
animation/configUpdate.js 193 bytes 5.65kB 3.53%
util/ReduceCSSCalc.js 863 bytes 5.55kB 18.42% ⚠️
util/DataUtils.js 158 bytes 5.13kB 3.18%
cartesian/getEquidistantTicks.js -39 bytes 4.34kB -0.89%
animation/easing.js 292 bytes 4.06kB 7.74% ⚠️
util/TickUtils.js -39 bytes 1.26kB -3.0%
util/getEveryNth.js (New) 802 bytes 802 bytes 100.0% 🚀
util/getEveryNthWithCondition.js (Deleted) -756 bytes 0 bytes -100.0% 🗑️
view changes for bundle: recharts/bundle-cjs

Assets Changed:

Asset Name Size Change Total Size Change (%)
cartesian/Area.js 477 bytes 28.39kB 1.71%
cartesian/Bar.js 114 bytes 27.18kB 0.42%
cartesian/ErrorBar.js 110 bytes 10.25kB 1.08%
util/isDomainSpecifiedByUser.js 41 bytes 7.6kB 0.54%
util/DataUtils.js 158 bytes 5.99kB 2.71%
animation/configUpdate.js 193 bytes 5.86kB 3.41%
util/ReduceCSSCalc.js 863 bytes 5.75kB 17.68% ⚠️
cartesian/getEquidistantTicks.js -52 bytes 4.58kB -1.12%
animation/easing.js 292 bytes 4.31kB 7.26% ⚠️
util/TickUtils.js -52 bytes 1.52kB -3.3%
util/getEveryNth.js (New) 910 bytes 910 bytes 100.0% 🚀
util/getEveryNthWithCondition.js (Deleted) -890 bytes 0 bytes -100.0% 🗑️
view changes for bundle: recharts/bundle-umd

Assets Changed:

Asset Name Size Change Total Size Change (%)
Recharts.js 1.09kB 517.16kB 0.21%

@ckifer ckifer merged commit 4b7616a into main Dec 7, 2025
37 of 39 checks passed
@ckifer ckifer deleted the ts-strict branch December 7, 2025 01:44
@coderabbitai coderabbitai bot mentioned this pull request Jan 1, 2026
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants