Skip to content

Commit fde64c3

Browse files
authored
Merge pull request #1737 from silx-kit/distributive
Make `ArrayValue` type distributive
2 parents 77b3ebf + 60462e7 commit fde64c3

File tree

7 files changed

+46
-49
lines changed

7 files changed

+46
-49
lines changed

eslint.config.base.js

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -822,6 +822,7 @@ export function createConfig(opts = {}) {
822822
'@typescript-eslint/no-unnecessary-parameter-property-assignment':
823823
'warn',
824824
'@typescript-eslint/no-unnecessary-qualifier': 'warn',
825+
'@typescript-eslint/no-unnecessary-type-arguments': 'warn', // downgrade
825826
'@typescript-eslint/no-unsafe-argument': 'warn',
826827
'@typescript-eslint/no-unsafe-assignment': 'off', // too tricky to fix when `any` is declared externally (JSON.parse, Array.isArray, etc.)
827828
'@typescript-eslint/no-unused-vars': [

packages/app/src/vis-packs/core/hooks.ts

Lines changed: 10 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -2,13 +2,14 @@ import { createMemo } from '@h5web/shared/createMemo';
22
import { assertDatasetValue, isDefined } from '@h5web/shared/guards';
33
import {
44
type ArrayShape,
5+
type ArrayValue,
56
type Dataset,
67
type ScalarShape,
78
type Value,
89
} from '@h5web/shared/hdf5-models';
910
import { type NumArray } from '@h5web/shared/vis-models';
1011
import { castArray } from '@h5web/shared/vis-utils';
11-
import { type NdArray, type TypedArray } from 'ndarray';
12+
import { type NdArray } from 'ndarray';
1213
import { useMemo } from 'react';
1314

1415
import { type DimensionMapping } from '../../dimension-mapper/models';
@@ -100,29 +101,29 @@ export function useDatasetValues<D extends Dataset<ArrayShape | ScalarShape>>(
100101
});
101102
}
102103

103-
export function useBaseArray<T extends unknown[] | TypedArray | undefined>(
104+
export function useBaseArray<T extends ArrayValue | undefined>(
104105
value: T,
105106
rawDims: number[],
106-
): T extends unknown[] | TypedArray ? NdArray<T> : undefined;
107+
): T extends ArrayValue ? NdArray<T> : undefined;
107108

108109
export function useBaseArray(
109-
value: unknown[] | TypedArray | undefined,
110+
value: ArrayValue | undefined,
110111
rawDims: number[],
111-
): NdArray<unknown[] | TypedArray> | undefined {
112+
): NdArray<ArrayValue> | undefined {
112113
return useMemo(() => getBaseArray(value, rawDims), [value, rawDims]);
113114
}
114115

115-
export function useMappedArray<T extends unknown[] | TypedArray | undefined>(
116+
export function useMappedArray<T extends ArrayValue | undefined>(
116117
value: T,
117118
dims: number[],
118119
mapping: DimensionMapping,
119-
): T extends unknown[] | TypedArray ? NdArray<T> : undefined;
120+
): T extends ArrayValue ? NdArray<T> : undefined;
120121

121122
export function useMappedArray(
122-
value: unknown[] | TypedArray | undefined,
123+
value: ArrayValue | undefined,
123124
dims: number[],
124125
mapping: DimensionMapping,
125-
): NdArray<unknown[] | TypedArray> | undefined {
126+
): NdArray<ArrayValue> | undefined {
126127
const baseArray = useBaseArray(value, dims);
127128

128129
return useMemo(() => applyMapping(baseArray, mapping), [baseArray, mapping]);

packages/app/src/vis-packs/core/utils.ts

Lines changed: 15 additions & 13 deletions
Original file line numberDiff line numberDiff line change
@@ -11,7 +11,7 @@ import {
1111
type NumArray,
1212
} from '@h5web/shared/vis-models';
1313
import { createArrayFromView } from '@h5web/shared/vis-utils';
14-
import ndarray, { type NdArray, type TypedArray } from 'ndarray';
14+
import ndarray, { type NdArray } from 'ndarray';
1515

1616
import { type DimensionMapping } from '../../dimension-mapper/models';
1717
import { isAxis } from '../../dimension-mapper/utils';
@@ -32,29 +32,27 @@ export const INTERACTIONS_WITH_AXIAL_ZOOM = [
3232
{ shortcut: 'Ctrl+Shift+Drag', description: 'Select to zoom in Y' },
3333
];
3434

35-
export function getBaseArray<T extends unknown[] | TypedArray | undefined>(
35+
export function getBaseArray<T extends ArrayValue | undefined>(
3636
value: T,
3737
rawDims: number[],
38-
): T extends unknown[] | TypedArray ? NdArray<T> : undefined;
38+
): T extends ArrayValue ? NdArray<T> : undefined;
3939

4040
export function getBaseArray(
41-
value: unknown[] | TypedArray | undefined,
41+
value: ArrayValue | undefined,
4242
rawDims: number[],
43-
): NdArray<unknown[] | TypedArray> | undefined {
43+
): NdArray<ArrayValue> | undefined {
4444
return value && ndarray(value, rawDims);
4545
}
4646

47-
export function applyMapping<
48-
T extends NdArray<unknown[] | TypedArray> | undefined,
49-
>(
47+
export function applyMapping<T extends NdArray<ArrayValue> | undefined>(
5048
baseArray: T,
5149
mapping: (number | Axis | ':')[],
52-
): T extends NdArray<unknown[] | TypedArray> ? T : undefined;
50+
): T extends NdArray<ArrayValue> ? T : undefined;
5351

5452
export function applyMapping(
55-
baseArray: NdArray<unknown[] | TypedArray> | undefined,
53+
baseArray: NdArray<ArrayValue> | undefined,
5654
mapping: (number | Axis | ':')[],
57-
): NdArray<unknown[] | TypedArray> | undefined {
55+
): NdArray<ArrayValue> | undefined {
5856
if (!baseArray) {
5957
return undefined;
6058
}
@@ -95,12 +93,16 @@ export function getImageInteractions(keepRatio: boolean): InteractionInfo[] {
9593
return keepRatio ? BASE_INTERACTIONS : INTERACTIONS_WITH_AXIAL_ZOOM;
9694
}
9795

96+
function isBoolArray(val: ArrayValue<NumericLikeType>): val is boolean[] {
97+
return Array.isArray(val) && typeof val[0] === 'boolean';
98+
}
99+
98100
export function toNumArray(arr: ArrayValue<NumericLikeType>): NumArray {
99-
if (typeof arr[0] === 'boolean') {
101+
if (isBoolArray(arr)) {
100102
return arr.map((val) => (val ? 1 : 0));
101103
}
102104

103-
return arr as NumArray;
105+
return arr;
104106
}
105107

106108
const TYPE_STRINGS: Record<NumericLikeType['class'], string> = {

packages/shared/src/guards.ts

Lines changed: 4 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -142,14 +142,6 @@ export function isTypedArray(val: unknown): val is TypedArray {
142142
);
143143
}
144144

145-
export function assertArrayOrTypedArray(
146-
val: unknown,
147-
): asserts val is unknown[] | TypedArray {
148-
if (!Array.isArray(val) && !isTypedArray(val)) {
149-
throw new TypeError('Expected array or typed array');
150-
}
151-
}
152-
153145
export function isGroup(entity: Entity): entity is Group {
154146
return entity.kind === EntityKind.Group;
155147
}
@@ -431,7 +423,7 @@ export function isComplexValue(
431423
function assertPrimitiveValue(
432424
type: DType,
433425
value: unknown,
434-
): asserts value is Primitive<DType> {
426+
): asserts value is Primitive {
435427
if (isNumericType(type)) {
436428
assertNum(value);
437429
} else if (isStringType(type)) {
@@ -457,7 +449,9 @@ export function assertDatasetValue<D extends Dataset<ScalarShape | ArrayShape>>(
457449
if (hasScalarShape(dataset)) {
458450
assertPrimitiveValue(type, value);
459451
} else {
460-
assertArrayOrTypedArray(value);
452+
if (!Array.isArray(value) && !isTypedArray(value)) {
453+
throw new TypeError('Expected array or typed array');
454+
}
461455

462456
if (value.length > 0) {
463457
assertPrimitiveValue(type, value[0]);

packages/shared/src/hdf5-models.ts

Lines changed: 11 additions & 13 deletions
Original file line numberDiff line numberDiff line change
@@ -207,21 +207,19 @@ export interface UnknownType {
207207
/* ----------------- */
208208
/* ----- VALUE ----- */
209209

210-
export type Primitive<T extends DType> = T extends NumericType | EnumType
211-
? number
210+
export type Primitive<T extends DType = DType> = T extends NumericLikeType
211+
? number | (T extends BooleanType ? boolean : never) // let providers choose how to return booleans
212212
: T extends StringType
213213
? string
214-
: T extends BooleanType
215-
? number | boolean // let providers choose
216-
: T extends ComplexType
217-
? H5WebComplex
218-
: T extends CompoundType<infer TFields>
219-
? Primitive<TFields>[]
220-
: unknown;
221-
222-
export type ArrayValue<T extends DType> =
223-
| Primitive<T>[]
224-
| (T extends NumericLikeType ? TypedArray : never);
214+
: T extends ComplexType
215+
? H5WebComplex
216+
: T extends CompoundType<infer TFields>
217+
? Primitive<TFields>[]
218+
: unknown;
219+
220+
export type ArrayValue<T extends DType = DType> = T extends NumericLikeType
221+
? TypedArray | number[] | (T extends BooleanType ? boolean[] : never) // don't use `Primitive` to avoid `(number | boolean)[]`
222+
: Primitive<T>[];
225223

226224
export type Value<D extends Dataset> =
227225
D extends Dataset<infer S, infer T>

packages/shared/src/mock-values.ts

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -2,7 +2,7 @@
22
import { range } from 'd3-array';
33
import ndarray, { type NdArray } from 'ndarray';
44

5-
import { type ArrayValue, type DType, type H5WebComplex } from './hdf5-models';
5+
import { type ArrayValue, type H5WebComplex } from './hdf5-models';
66
import { cplx } from './hdf5-utils';
77

88
const range1 = () => range(-20, 21);
@@ -276,4 +276,4 @@ export const mockValues = {
276276
ndarray(range1().map((val) => Math.cos((val * 3.14) / 40))),
277277
Y_scatter: () =>
278278
ndarray(range1().map((_, i) => ((i % 10) + (i % 5)) / 123_456)),
279-
} satisfies Record<string, () => NdArray<ArrayValue<DType>>>;
279+
} satisfies Record<string, () => NdArray<ArrayValue>>;

packages/shared/src/vis-utils.ts

Lines changed: 3 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,9 +1,10 @@
11
import { format } from 'd3-format';
2-
import ndarray, { type NdArray, type TypedArray } from 'ndarray';
2+
import ndarray, { type NdArray } from 'ndarray';
33
import { assign } from 'ndarray-ops';
44

55
import { assertLength, isNdArray } from './guards';
66
import {
7+
type ArrayValue,
78
type BooleanType,
89
type ComplexType,
910
type EnumType,
@@ -101,7 +102,7 @@ export function toTypedNdArray<T extends TypedArrayConstructor>(
101102
return ndarray(Constructor.from(arr.data) as InstanceType<T>, arr.shape);
102103
}
103104

104-
export function createArrayFromView<T extends TypedArray | unknown[]>(
105+
export function createArrayFromView<T extends ArrayValue>(
105106
view: NdArray<T>,
106107
): NdArray<T> {
107108
const { data, size, shape } = view;

0 commit comments

Comments
 (0)