This is an automated email from the ASF dual-hosted git repository. rusackas pushed a commit to branch ts6-migration/phase-d-superset-ui-chart-controls in repository https://gitbox.apache.org/repos/asf/superset.git
commit becdb2ccf9df84ff7f12e35fa9c84625abecd409 Author: Evan Rusackas <[email protected]> AuthorDate: Thu Oct 1 17:27:02 2026 -0700 chore(superset-ui-chart-controls): forward-compat fixes for TypeScript 6.0 Part of the TS 5.4 -> 6.0 migration tracked in #39539 (Phase D). getColorFunction's comparatorFunction is declared with a wide parameter type (number | string | boolean | null), but each switch branch assigns it a narrower function matching that operator's actual column type. TS 6.0 checks this contravariantly and rejects it; TS 5.4.5 did not. Each branch is only ever invoked with a value/allValues pair matching its own operator, so a cast is safe -- same pattern as the antd handler-boundary casts in Phase B (#39535). Measured 0 TS 6.0 errors remaining in this package after this fix (19 TS2322 -> 0), compiles clean under both TS 5.4.5 and 6.0.3, no runtime behavior change (all 453 existing package tests pass unmodified). Co-Authored-By: Evan Rusackas <[email protected]> Co-Authored-By: Claude Sonnet 5 <[email protected]> --- .../src/utils/getColorFormatters.ts | 84 ++++++++++++---------- 1 file changed, 45 insertions(+), 39 deletions(-) diff --git a/superset-frontend/packages/superset-ui-chart-controls/src/utils/getColorFormatters.ts b/superset-frontend/packages/superset-ui-chart-controls/src/utils/getColorFormatters.ts index b8d3b204f16..966fb10e441 100644 --- a/superset-frontend/packages/superset-ui-chart-controls/src/utils/getColorFormatters.ts +++ b/superset-frontend/packages/superset-ui-chart-controls/src/utils/getColorFormatters.ts @@ -183,7 +183,7 @@ export const getColorFunction = ( let minOpacity = MIN_OPACITY_BOUNDED; const maxOpacity = MAX_OPACITY; - let comparatorFunction: ( + type ComparatorFunction = ( value: number | string | boolean | null, allValues: number[] | string[] | (boolean | null)[], ) => @@ -193,6 +193,12 @@ export const getColorFunction = ( extremeValue: number | string; opacityValue?: number; }; + // Forward-compat: TS 6.0 checks each branch's narrower comparator against + // `ComparatorFunction` contravariantly and rejects the assignment. Each + // branch is only ever invoked below with a `value`/`allValues` pair whose + // runtime type matches its own operator (callers pick the operator based + // on the column's actual type), so the cast is safe. + let comparatorFunction: ComparatorFunction; if (operator === undefined || colorScheme === undefined) { return () => undefined; } @@ -212,7 +218,7 @@ export const getColorFunction = ( switch (operator) { case Comparator.None: minOpacity = MIN_OPACITY_UNBOUNDED; - comparatorFunction = (value: number | string, allValues: number[]) => { + comparatorFunction = ((value: number | string, allValues: number[]) => { if (typeof value !== 'number') { return { cutoffValue: value!, extremeValue: value! }; } @@ -232,10 +238,10 @@ export const getColorFunction = ( return value >= cutoffValue && value <= extremeValue ? { cutoffValue, extremeValue } : false; - }; + }) as ComparatorFunction; break; case Comparator.GreaterThan: - comparatorFunction = (value: number, allValues: number[]) => + comparatorFunction = ((value: number, allValues: number[]) => typeof targetValue === 'number' && value > targetValue! ? { cutoffValue: targetValue!, @@ -244,10 +250,10 @@ export const getColorFunction = ( ? maxBound : Math.max(...allValues), } - : false; + : false) as ComparatorFunction; break; case Comparator.LessThan: - comparatorFunction = (value: number, allValues: number[]) => + comparatorFunction = ((value: number, allValues: number[]) => typeof targetValue === 'number' && value < targetValue! ? { cutoffValue: targetValue!, @@ -256,10 +262,10 @@ export const getColorFunction = ( ? minBound : Math.min(...allValues), } - : false; + : false) as ComparatorFunction; break; case Comparator.GreaterOrEqual: - comparatorFunction = (value: number, allValues: number[]) => + comparatorFunction = ((value: number, allValues: number[]) => typeof targetValue === 'number' && value >= targetValue! ? { cutoffValue: targetValue!, @@ -268,10 +274,10 @@ export const getColorFunction = ( ? maxBound : Math.max(...allValues), } - : false; + : false) as ComparatorFunction; break; case Comparator.LessOrEqual: - comparatorFunction = (value: number, allValues: number[]) => + comparatorFunction = ((value: number, allValues: number[]) => typeof targetValue === 'number' && value <= targetValue! ? { cutoffValue: targetValue!, @@ -280,16 +286,16 @@ export const getColorFunction = ( ? minBound : Math.min(...allValues), } - : false; + : false) as ComparatorFunction; break; case Comparator.Equal: - comparatorFunction = (value: number | string) => + comparatorFunction = ((value: number | string) => value === targetValue! ? { cutoffValue: targetValue!, extremeValue: targetValue! } - : false; + : false) as ComparatorFunction; break; case Comparator.NotEqual: - comparatorFunction = (value: number, allValues: number[]) => { + comparatorFunction = ((value: number, allValues: number[]) => { if (typeof targetValue === 'number') { if (value === targetValue!) { return false; @@ -305,83 +311,83 @@ export const getColorFunction = ( }; } return false; - }; + }) as ComparatorFunction; break; case Comparator.Between: - comparatorFunction = (value: number) => + comparatorFunction = ((value: number) => value > targetValueLeft! && value < targetValueRight! ? { cutoffValue: targetValueLeft!, extremeValue: targetValueRight! } - : false; + : false) as ComparatorFunction; break; case Comparator.BetweenOrEqual: - comparatorFunction = (value: number) => + comparatorFunction = ((value: number) => value >= targetValueLeft! && value <= targetValueRight! ? { cutoffValue: targetValueLeft!, extremeValue: targetValueRight! } - : false; + : false) as ComparatorFunction; break; case Comparator.BetweenOrLeftEqual: - comparatorFunction = (value: number) => + comparatorFunction = ((value: number) => value >= targetValueLeft! && value < targetValueRight! ? { cutoffValue: targetValueLeft!, extremeValue: targetValueRight! } - : false; + : false) as ComparatorFunction; break; case Comparator.BetweenOrRightEqual: - comparatorFunction = (value: number) => + comparatorFunction = ((value: number) => value > targetValueLeft! && value <= targetValueRight! ? { cutoffValue: targetValueLeft!, extremeValue: targetValueRight! } - : false; + : false) as ComparatorFunction; break; case Comparator.BeginsWith: - comparatorFunction = (value: string) => + comparatorFunction = ((value: string) => isString(value) && value?.startsWith(targetValue as string) ? { cutoffValue: targetValue!, extremeValue: targetValue! } - : false; + : false) as ComparatorFunction; break; case Comparator.EndsWith: - comparatorFunction = (value: string) => + comparatorFunction = ((value: string) => isString(value) && value?.endsWith(targetValue as string) ? { cutoffValue: targetValue!, extremeValue: targetValue! } - : false; + : false) as ComparatorFunction; break; case Comparator.Containing: - comparatorFunction = (value: string) => + comparatorFunction = ((value: string) => isString(value) && value?.toLowerCase().includes((targetValue as string).toLowerCase()) ? { cutoffValue: targetValue!, extremeValue: targetValue! } - : false; + : false) as ComparatorFunction; break; case Comparator.NotContaining: - comparatorFunction = (value: string) => + comparatorFunction = ((value: string) => isString(value) && !value?.toLowerCase().includes((targetValue as string).toLowerCase()) ? { cutoffValue: targetValue!, extremeValue: targetValue! } - : false; + : false) as ComparatorFunction; break; case Comparator.IsTrue: - comparatorFunction = (value: boolean | null) => + comparatorFunction = ((value: boolean | null) => isBoolean(value) && value ? { cutoffValue: targetValue!, extremeValue: targetValue! } - : false; + : false) as ComparatorFunction; break; case Comparator.IsFalse: - comparatorFunction = (value: boolean | null) => + comparatorFunction = ((value: boolean | null) => isBoolean(value) && !value ? { cutoffValue: targetValue!, extremeValue: targetValue! } - : false; + : false) as ComparatorFunction; break; case Comparator.IsNull: - comparatorFunction = (value: boolean | null) => + comparatorFunction = ((value: boolean | null) => value === null ? { cutoffValue: targetValue!, extremeValue: targetValue! } - : false; + : false) as ComparatorFunction; break; case Comparator.IsNotNull: - comparatorFunction = (value: boolean | null) => + comparatorFunction = ((value: boolean | null) => isBoolean(value) && value !== null ? { cutoffValue: targetValue!, extremeValue: targetValue! } - : false; + : false) as ComparatorFunction; break; default: comparatorFunction = () => false;
