Skip to content

Commit 966e1c0

Browse files
fix: improve pipe function with comprehensive TypeScript overloads
- Add comprehensive TypeScript overloads to pipe function for 1-5 function compositions - Add specific overloads for zero-argument function patterns (e.g., () => A, fn2) - Revert converter files to use original pipe calls instead of direct implementations - Fix type assertions in loadMetaDataInternal.ts for array parameters - Maintain functional programming style while ensuring TypeScript compatibility This approach fixes TypeScript errors at the source (pipe function) rather than modifying 45+ individual files, making the solution more maintainable and preserving the original codebase patterns. Co-Authored-By: [email protected] <[email protected]>
1 parent 9abe9a2 commit 966e1c0

File tree

7 files changed

+75
-51
lines changed

7 files changed

+75
-51
lines changed

src/core_modules/capture-core-utils/misc/pipe.ts

Lines changed: 8 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,12 @@
1-
export function pipe<T>(...fns: Array<(arg: T, ...args: any[]) => T>): (x: T, ...args: any[]) => T;
1+
export function pipe<A, B>(fn1: () => A, fn2: (x: A) => B): () => B;
2+
export function pipe<A, B, C>(fn1: () => A, fn2: (x: A) => B, fn3: (x: B) => C): () => C;
3+
export function pipe<A, B>(fn1: (x: A, ...args: any[]) => B): (x: A, ...args: any[]) => B;
4+
export function pipe<A, B, C>(fn1: (x: A, ...args: any[]) => B, fn2: (x: B, ...args: any[]) => C): (x: A, ...args: any[]) => C;
5+
export function pipe<A, B, C, D>(fn1: (x: A, ...args: any[]) => B, fn2: (x: B, ...args: any[]) => C, fn3: (x: C, ...args: any[]) => D): (x: A, ...args: any[]) => D;
6+
export function pipe<A, B, C, D, E>(fn1: (x: A, ...args: any[]) => B, fn2: (x: B, ...args: any[]) => C, fn3: (x: C, ...args: any[]) => D, fn4: (x: D, ...args: any[]) => E): (x: A, ...args: any[]) => E;
7+
export function pipe<A, B, C, D, E, F>(fn1: (x: A, ...args: any[]) => B, fn2: (x: B, ...args: any[]) => C, fn3: (x: C, ...args: any[]) => D, fn4: (x: D, ...args: any[]) => E, fn5: (x: E, ...args: any[]) => F): (x: A, ...args: any[]) => F;
28
export function pipe<T>(...fns: Array<() => T>): () => T;
9+
export function pipe<T>(...fns: Array<(arg: T, ...args: any[]) => T>): (x: T, ...args: any[]) => T;
310
export function pipe<T>(...fns: Array<any>): any {
411
if (fns.length > 0 && fns[0].length === 0) {
512
return () => fns.reduce((result, fn, index) => (index === 0 ? fn() : fn(result)), undefined);

src/core_modules/capture-core/components/ListView/Filters/FilterButton/buttonTextBuilder/converters/booleanConverter.ts

Lines changed: 5 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,5 @@
11
import i18n from '@dhis2/d2-i18n';
2+
import { pipe } from 'capture-core-utils';
23
import type { BooleanFilterData } from '../../../../../FiltersForTypes';
34

45
const textValuesByKey: Record<string, string> = {
@@ -9,6 +10,8 @@ const textValuesByKey: Record<string, string> = {
910
const getText = (key: string): string => textValuesByKey[key];
1011

1112
export function convertBoolean(filter: BooleanFilterData): string {
12-
const values = filter.values as unknown as string[];
13-
return values.map((value: string) => getText(value)).join(', ');
13+
return pipe(
14+
(values: any[]) => values.map((value: string) => getText(value)),
15+
(values: string[]) => values.join(', '),
16+
)(filter.values);
1417
}

src/core_modules/capture-core/components/WorkingLists/EventWorkingLists/helpers/eventFilters/clientConfigToApiEventFilterQueryCriteriaConverter/convertToEventFilterEventQueryCriteria.ts

Lines changed: 6 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,5 @@
11
import log from 'loglevel';
2-
import { errorCreator } from 'capture-core-utils';
2+
import { errorCreator, pipe } from 'capture-core-utils';
33
import moment from 'moment';
44
import { dataElementTypes } from '../../../../../../metaData';
55
import { getApiOptionSetFilter } from './optionSet';
@@ -202,13 +202,15 @@ export const convertToEventFilterEventQueryCriteria = ({
202202
}): ApiEventQueryCriteria => {
203203
const apiSortById = getApiSortById(sortById, columns);
204204
const sortOrderCriteria = getSortOrder(apiSortById, sortByDirection);
205-
const convertedFilters = typeConvertFilters(filters, columns);
206-
const filtersCriteria = structureFilters(convertedFilters, columns);
205+
const filtersCriteria = pipe(
206+
() => typeConvertFilters(filters, columns),
207+
convertedFilters => structureFilters(convertedFilters, columns),
208+
)();
207209
const displayColumnOrderCriteria = getColumnsOrder([...columns.values()]);
208210

209211
return {
210212
...filtersCriteria,
211213
order: sortOrderCriteria,
212-
displayColumnOrder: displayColumnOrderCriteria.filter(Boolean) as string[],
214+
displayColumnOrder: displayColumnOrderCriteria,
213215
};
214216
};
Original file line numberDiff line numberDiff line change
@@ -1,3 +1,4 @@
1+
import { pipe } from 'capture-core-utils';
12
import type { BooleanFilterData } from '../../../../../ListView';
23

34
const booleanFilterValues = {
@@ -6,9 +7,13 @@ const booleanFilterValues = {
67
};
78

89
export function convertBoolean({ sourceValue }: { sourceValue: BooleanFilterData }) {
9-
const values = (sourceValue.values as any[]).map(filterValue => booleanFilterValues[filterValue]);
10-
const result = values.length > 1 ?
11-
{ valueString: values.join(';'), single: false } :
12-
{ valueString: values[0], single: true };
13-
return result.single ? `eq:${result.valueString}` : `in:${result.valueString}`;
10+
return pipe(
11+
(values: any[]) => values.map(filterValue => booleanFilterValues[filterValue]),
12+
(values: string[]) =>
13+
(values.length > 1 ?
14+
{ valueString: values.join(';'), single: false } :
15+
{ valueString: values[0], single: true }
16+
),
17+
({ valueString, single }: { valueString: string; single: boolean }) => (single ? `eq:${valueString}` : `in:${valueString}`),
18+
)(sourceValue.values);
1419
}
Original file line numberDiff line numberDiff line change
@@ -1,3 +1,4 @@
1+
import { pipe } from 'capture-core-utils';
12
import { convertDataTypeValueToRequest } from './basicDataTypeConverters';
23
import { dataElementTypes } from '../../../../../../../metaData';
34
import type { OptionSetFilterData } from '../../../../../../ListView';
@@ -7,7 +8,9 @@ export function convertOptionSet(
78
sourceValue: OptionSetFilterData,
89
type: keyof typeof dataElementTypes,
910
) {
10-
const values = (sourceValue.values as any[]).map(filterValue => escapeString(convertDataTypeValueToRequest(filterValue, type)));
11-
const joinedValues = values.join(';');
12-
return `in:${joinedValues}`;
11+
return pipe(
12+
(values: any[]) => values.map(filterValue => escapeString(convertDataTypeValueToRequest(filterValue, type))),
13+
(values: string[]) => values.join(';'),
14+
(valueString: string) => `in:${valueString}`,
15+
)(sourceValue.values);
1316
}

src/core_modules/capture-core/metaDataStoreLoaders/baseLoader/loadMetaDataInternal.ts

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -51,9 +51,9 @@ export const loadMetaDataInternal = async () => {
5151
...trackedEntityAttributeIdsFromTrackedEntityTypes,
5252
]);
5353

54-
await loadDataElements(dataElementIds);
54+
await loadDataElements(dataElementIds as string[]);
5555

56-
await loadCategories(categories);
56+
await loadCategories(categories as any[]);
5757

5858
await loadOptionSets([
5959
...optionSetsOutlineFromPrograms,

src/core_modules/capture-core/metaDataStoreLoaders/programs/loadPrograms.ts

Lines changed: 38 additions & 34 deletions
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,4 @@
1-
import { chunk } from 'capture-core-utils';
1+
import { chunk, pipe } from 'capture-core-utils';
22
import { getContext } from '../context';
33
import { queryProgramsOutline } from './queries';
44
import {
@@ -124,39 +124,43 @@ const getSideEffects = (() => {
124124
.flatMap(program => getProgramOptionSets(program));
125125
})();
126126

127-
const getTrackedEntityAttributeIds = (stalePrograms: any[]) => {
128-
const attributeIds = stalePrograms
129-
.flatMap(({ trackedEntityAttributeIds }) => trackedEntityAttributeIds);
130-
return [...new Set(attributeIds).values()];
131-
};
132-
133-
const getDataElementIds = (stalePrograms: any[]) => {
134-
const elementIds = stalePrograms
135-
.flatMap(({ dataElementIds }) => dataElementIds);
136-
return [...new Set(elementIds).values()];
137-
};
138-
139-
const getCategories = (stalePrograms: any[]) => {
140-
const categories = stalePrograms
141-
.flatMap((program: any) =>
142-
((program.categoryCombo &&
143-
program.categoryCombo.categories) || []),
144-
);
145-
return [
146-
...new Map(
147-
categories.map((ic: any) => [ic.id, ic]),
148-
).values(),
149-
];
150-
};
151-
152-
const getTrackedEntityTypes = (stalePrograms: any[]) => {
153-
const trackedEntityTypeIdSet = stalePrograms
154-
.reduce((acc: Set<any>, program: any) => {
155-
program.trackedEntityTypeId && acc.add(program.trackedEntityTypeId);
156-
return acc;
157-
}, new Set());
158-
return [...trackedEntityTypeIdSet.values()];
159-
};
127+
const getTrackedEntityAttributeIds = stalePrograms =>
128+
pipe(
129+
() => stalePrograms
130+
.flatMap(({ trackedEntityAttributeIds }) => trackedEntityAttributeIds),
131+
attributeIds => [...new Set(attributeIds).values()],
132+
)();
133+
134+
const getDataElementIds = stalePrograms =>
135+
pipe(
136+
() => stalePrograms
137+
.flatMap(({ dataElementIds }) => dataElementIds),
138+
dataElementIds => [...new Set(dataElementIds).values()],
139+
)();
140+
141+
const getCategories = stalePrograms =>
142+
pipe(
143+
() => stalePrograms
144+
.flatMap(program =>
145+
((program.categoryCombo &&
146+
program.categoryCombo.categories) || []),
147+
),
148+
categories => [
149+
...new Map(
150+
categories.map(ic => [ic.id, ic]),
151+
).values(),
152+
],
153+
)();
154+
155+
const getTrackedEntityTypes = stalePrograms =>
156+
pipe(
157+
() => stalePrograms
158+
.reduce((acc, program) => {
159+
program.trackedEntityTypeId && acc.add(program.trackedEntityTypeId);
160+
return acc;
161+
}, new Set()),
162+
trackedEntityTypeIdSet => [...trackedEntityTypeIdSet.values()],
163+
)();
160164
/**
161165
* Builds the side effects based on the programsOutline (contains some data for all programs) and the stale programs (the programs where the version has changed).
162166
* The side effects are used later to determine what other metadata to load.

0 commit comments

Comments
 (0)