@visulima/object 1.0.8 → 1.0.9
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/CHANGELOG.md +12 -0
- package/README.md +1 -1
- package/dist/index.d.cts +78 -70
- package/dist/index.d.mts +78 -70
- package/dist/index.d.ts +78 -70
- package/package.json +2 -68
package/CHANGELOG.md
CHANGED
|
@@ -1,3 +1,15 @@
|
|
|
1
|
+
## @visulima/object [1.0.9](https://github.com/visulima/visulima/compare/@visulima/object@1.0.8...@visulima/object@1.0.9) (2025-01-25)
|
|
2
|
+
|
|
3
|
+
### Bug Fixes
|
|
4
|
+
|
|
5
|
+
* fixed wrong node version range in package.json ([4ae2929](https://github.com/visulima/visulima/commit/4ae292984681c71a770e4d4560432f7b7c5a141a))
|
|
6
|
+
|
|
7
|
+
### Miscellaneous Chores
|
|
8
|
+
|
|
9
|
+
* fixed typescript url ([fe65a8c](https://github.com/visulima/visulima/commit/fe65a8c0296ece7ee26474c70d065b06d4d0da89))
|
|
10
|
+
* updated all dev dependencies ([37fb298](https://github.com/visulima/visulima/commit/37fb298b2af7c63be64252024e54bb3af6ddabec))
|
|
11
|
+
* updated all dev dependencies and all dependencies in the app folder ([87f4ccb](https://github.com/visulima/visulima/commit/87f4ccbf9f7900ec5b56f3c1477bc4a0ef571bcf))
|
|
12
|
+
|
|
1
13
|
## @visulima/object [1.0.8](https://github.com/visulima/visulima/compare/@visulima/object@1.0.7...@visulima/object@1.0.8) (2025-01-12)
|
|
2
14
|
|
|
3
15
|
### Bug Fixes
|
package/README.md
CHANGED
|
@@ -129,7 +129,7 @@ If you would like to help take a look at the [list of issues](https://github.com
|
|
|
129
129
|
The visulima object is open-sourced software licensed under the [MIT][license-url]
|
|
130
130
|
|
|
131
131
|
[typescript-image]: https://img.shields.io/badge/Typescript-294E80.svg?style=for-the-badge&logo=typescript
|
|
132
|
-
[typescript-url]: "typescript"
|
|
132
|
+
[typescript-url]: https://www.typescriptlang.org/ "TypeScript" "typescript"
|
|
133
133
|
[license-image]: https://img.shields.io/npm/l/@visulima/object?color=blueviolet&style=for-the-badge
|
|
134
134
|
[license-url]: LICENSE.md "license"
|
|
135
135
|
[npm-image]: https://img.shields.io/npm/v/@visulima/object/latest.svg?style=for-the-badge&logo=npm
|
package/dist/index.d.cts
CHANGED
|
@@ -19,6 +19,68 @@ declare global {
|
|
|
19
19
|
}
|
|
20
20
|
}
|
|
21
21
|
|
|
22
|
+
/**
|
|
23
|
+
Convert a union type to an intersection type using [distributive conditional types](https://www.typescriptlang.org/docs/handbook/release-notes/typescript-2-8.html#distributive-conditional-types).
|
|
24
|
+
|
|
25
|
+
Inspired by [this Stack Overflow answer](https://stackoverflow.com/a/50375286/2172153).
|
|
26
|
+
|
|
27
|
+
@example
|
|
28
|
+
```
|
|
29
|
+
import type {UnionToIntersection} from 'type-fest';
|
|
30
|
+
|
|
31
|
+
type Union = {the(): void} | {great(arg: string): void} | {escape: boolean};
|
|
32
|
+
|
|
33
|
+
type Intersection = UnionToIntersection<Union>;
|
|
34
|
+
//=> {the(): void; great(arg: string): void; escape: boolean};
|
|
35
|
+
```
|
|
36
|
+
|
|
37
|
+
A more applicable example which could make its way into your library code follows.
|
|
38
|
+
|
|
39
|
+
@example
|
|
40
|
+
```
|
|
41
|
+
import type {UnionToIntersection} from 'type-fest';
|
|
42
|
+
|
|
43
|
+
class CommandOne {
|
|
44
|
+
commands: {
|
|
45
|
+
a1: () => undefined,
|
|
46
|
+
b1: () => undefined,
|
|
47
|
+
}
|
|
48
|
+
}
|
|
49
|
+
|
|
50
|
+
class CommandTwo {
|
|
51
|
+
commands: {
|
|
52
|
+
a2: (argA: string) => undefined,
|
|
53
|
+
b2: (argB: string) => undefined,
|
|
54
|
+
}
|
|
55
|
+
}
|
|
56
|
+
|
|
57
|
+
const union = [new CommandOne(), new CommandTwo()].map(instance => instance.commands);
|
|
58
|
+
type Union = typeof union;
|
|
59
|
+
//=> {a1(): void; b1(): void} | {a2(argA: string): void; b2(argB: string): void}
|
|
60
|
+
|
|
61
|
+
type Intersection = UnionToIntersection<Union>;
|
|
62
|
+
//=> {a1(): void; b1(): void; a2(argA: string): void; b2(argB: string): void}
|
|
63
|
+
```
|
|
64
|
+
|
|
65
|
+
@category Type
|
|
66
|
+
*/
|
|
67
|
+
type UnionToIntersection<Union> = (
|
|
68
|
+
// `extends unknown` is always going to be the case and is used to convert the
|
|
69
|
+
// `Union` into a [distributive conditional
|
|
70
|
+
// type](https://www.typescriptlang.org/docs/handbook/release-notes/typescript-2-8.html#distributive-conditional-types).
|
|
71
|
+
Union extends unknown
|
|
72
|
+
// The union type is used as the only argument to a function since the union
|
|
73
|
+
// of function arguments is an intersection.
|
|
74
|
+
? (distributedUnion: Union) => void
|
|
75
|
+
// This won't happen.
|
|
76
|
+
: never
|
|
77
|
+
// Infer the `Intersection` type since TypeScript represents the positional
|
|
78
|
+
// arguments of unions of functions as an intersection of the union.
|
|
79
|
+
) extends ((mergedIntersection: infer Intersection) => void)
|
|
80
|
+
// The `& Union` is to allow indexing by the resulting type
|
|
81
|
+
? Intersection & Union
|
|
82
|
+
: never;
|
|
83
|
+
|
|
22
84
|
declare const emptyObjectSymbol: unique symbol;
|
|
23
85
|
|
|
24
86
|
/**
|
|
@@ -560,9 +622,11 @@ If `<Fill>` is not provided, it will default to `unknown`.
|
|
|
560
622
|
|
|
561
623
|
@link https://itnext.io/implementing-arithmetic-within-typescripts-type-system-a1ef140a6f6f
|
|
562
624
|
*/
|
|
563
|
-
type BuildTuple<L extends number, Fill = unknown, T extends readonly unknown[] = []> =
|
|
564
|
-
?
|
|
565
|
-
:
|
|
625
|
+
type BuildTuple<L extends number, Fill = unknown, T extends readonly unknown[] = []> = number extends L
|
|
626
|
+
? Fill[]
|
|
627
|
+
: L extends T['length']
|
|
628
|
+
? T
|
|
629
|
+
: BuildTuple<L, Fill, [...T, Fill]>;
|
|
566
630
|
|
|
567
631
|
/**
|
|
568
632
|
Returns the maximum value from a tuple of integers.
|
|
@@ -1337,68 +1401,6 @@ type InternalPaths<T, Options extends Required<PathsOptions>> =
|
|
|
1337
1401
|
: never
|
|
1338
1402
|
: never;
|
|
1339
1403
|
|
|
1340
|
-
/**
|
|
1341
|
-
Convert a union type to an intersection type using [distributive conditional types](https://www.typescriptlang.org/docs/handbook/release-notes/typescript-2-8.html#distributive-conditional-types).
|
|
1342
|
-
|
|
1343
|
-
Inspired by [this Stack Overflow answer](https://stackoverflow.com/a/50375286/2172153).
|
|
1344
|
-
|
|
1345
|
-
@example
|
|
1346
|
-
```
|
|
1347
|
-
import type {UnionToIntersection} from 'type-fest';
|
|
1348
|
-
|
|
1349
|
-
type Union = {the(): void} | {great(arg: string): void} | {escape: boolean};
|
|
1350
|
-
|
|
1351
|
-
type Intersection = UnionToIntersection<Union>;
|
|
1352
|
-
//=> {the(): void; great(arg: string): void; escape: boolean};
|
|
1353
|
-
```
|
|
1354
|
-
|
|
1355
|
-
A more applicable example which could make its way into your library code follows.
|
|
1356
|
-
|
|
1357
|
-
@example
|
|
1358
|
-
```
|
|
1359
|
-
import type {UnionToIntersection} from 'type-fest';
|
|
1360
|
-
|
|
1361
|
-
class CommandOne {
|
|
1362
|
-
commands: {
|
|
1363
|
-
a1: () => undefined,
|
|
1364
|
-
b1: () => undefined,
|
|
1365
|
-
}
|
|
1366
|
-
}
|
|
1367
|
-
|
|
1368
|
-
class CommandTwo {
|
|
1369
|
-
commands: {
|
|
1370
|
-
a2: (argA: string) => undefined,
|
|
1371
|
-
b2: (argB: string) => undefined,
|
|
1372
|
-
}
|
|
1373
|
-
}
|
|
1374
|
-
|
|
1375
|
-
const union = [new CommandOne(), new CommandTwo()].map(instance => instance.commands);
|
|
1376
|
-
type Union = typeof union;
|
|
1377
|
-
//=> {a1(): void; b1(): void} | {a2(argA: string): void; b2(argB: string): void}
|
|
1378
|
-
|
|
1379
|
-
type Intersection = UnionToIntersection<Union>;
|
|
1380
|
-
//=> {a1(): void; b1(): void; a2(argA: string): void; b2(argB: string): void}
|
|
1381
|
-
```
|
|
1382
|
-
|
|
1383
|
-
@category Type
|
|
1384
|
-
*/
|
|
1385
|
-
type UnionToIntersection<Union> = (
|
|
1386
|
-
// `extends unknown` is always going to be the case and is used to convert the
|
|
1387
|
-
// `Union` into a [distributive conditional
|
|
1388
|
-
// type](https://www.typescriptlang.org/docs/handbook/release-notes/typescript-2-8.html#distributive-conditional-types).
|
|
1389
|
-
Union extends unknown
|
|
1390
|
-
// The union type is used as the only argument to a function since the union
|
|
1391
|
-
// of function arguments is an intersection.
|
|
1392
|
-
? (distributedUnion: Union) => void
|
|
1393
|
-
// This won't happen.
|
|
1394
|
-
: never
|
|
1395
|
-
// Infer the `Intersection` type since TypeScript represents the positional
|
|
1396
|
-
// arguments of unions of functions as an intersection of the union.
|
|
1397
|
-
) extends ((mergedIntersection: infer Intersection) => void)
|
|
1398
|
-
// The `& Union` is to allow indexing by the resulting type
|
|
1399
|
-
? Intersection & Union
|
|
1400
|
-
: never;
|
|
1401
|
-
|
|
1402
1404
|
/**
|
|
1403
1405
|
Pick properties from a deeply-nested object.
|
|
1404
1406
|
|
|
@@ -2040,11 +2042,17 @@ array = split(items, ',');
|
|
|
2040
2042
|
type Split<
|
|
2041
2043
|
S extends string,
|
|
2042
2044
|
Delimiter extends string,
|
|
2045
|
+
> = SplitHelper<S, Delimiter>;
|
|
2046
|
+
|
|
2047
|
+
type SplitHelper<
|
|
2048
|
+
S extends string,
|
|
2049
|
+
Delimiter extends string,
|
|
2050
|
+
Accumulator extends string[] = [],
|
|
2043
2051
|
> = S extends `${infer Head}${Delimiter}${infer Tail}`
|
|
2044
|
-
?
|
|
2045
|
-
:
|
|
2046
|
-
?
|
|
2047
|
-
: [S];
|
|
2052
|
+
? SplitHelper<Tail, Delimiter, [...Accumulator, Head]>
|
|
2053
|
+
: Delimiter extends ''
|
|
2054
|
+
? Accumulator
|
|
2055
|
+
: [...Accumulator, S];
|
|
2048
2056
|
|
|
2049
2057
|
type GetOptions = {
|
|
2050
2058
|
/**
|
|
@@ -2247,7 +2255,7 @@ type Get<
|
|
|
2247
2255
|
BaseType,
|
|
2248
2256
|
Path extends
|
|
2249
2257
|
| readonly string[]
|
|
2250
|
-
| LiteralStringUnion<ToString<Paths<BaseType, {bracketNotation: false}> | Paths<BaseType, {bracketNotation: true}>>>,
|
|
2258
|
+
| LiteralStringUnion<ToString<Paths<BaseType, {bracketNotation: false; maxRecursionDepth: 2}> | Paths<BaseType, {bracketNotation: true; maxRecursionDepth: 2}>>>,
|
|
2251
2259
|
Options extends GetOptions = {}> =
|
|
2252
2260
|
GetWithPath<BaseType, Path extends string ? ToPath<Path> : Path, Options>;
|
|
2253
2261
|
|
package/dist/index.d.mts
CHANGED
|
@@ -19,6 +19,68 @@ declare global {
|
|
|
19
19
|
}
|
|
20
20
|
}
|
|
21
21
|
|
|
22
|
+
/**
|
|
23
|
+
Convert a union type to an intersection type using [distributive conditional types](https://www.typescriptlang.org/docs/handbook/release-notes/typescript-2-8.html#distributive-conditional-types).
|
|
24
|
+
|
|
25
|
+
Inspired by [this Stack Overflow answer](https://stackoverflow.com/a/50375286/2172153).
|
|
26
|
+
|
|
27
|
+
@example
|
|
28
|
+
```
|
|
29
|
+
import type {UnionToIntersection} from 'type-fest';
|
|
30
|
+
|
|
31
|
+
type Union = {the(): void} | {great(arg: string): void} | {escape: boolean};
|
|
32
|
+
|
|
33
|
+
type Intersection = UnionToIntersection<Union>;
|
|
34
|
+
//=> {the(): void; great(arg: string): void; escape: boolean};
|
|
35
|
+
```
|
|
36
|
+
|
|
37
|
+
A more applicable example which could make its way into your library code follows.
|
|
38
|
+
|
|
39
|
+
@example
|
|
40
|
+
```
|
|
41
|
+
import type {UnionToIntersection} from 'type-fest';
|
|
42
|
+
|
|
43
|
+
class CommandOne {
|
|
44
|
+
commands: {
|
|
45
|
+
a1: () => undefined,
|
|
46
|
+
b1: () => undefined,
|
|
47
|
+
}
|
|
48
|
+
}
|
|
49
|
+
|
|
50
|
+
class CommandTwo {
|
|
51
|
+
commands: {
|
|
52
|
+
a2: (argA: string) => undefined,
|
|
53
|
+
b2: (argB: string) => undefined,
|
|
54
|
+
}
|
|
55
|
+
}
|
|
56
|
+
|
|
57
|
+
const union = [new CommandOne(), new CommandTwo()].map(instance => instance.commands);
|
|
58
|
+
type Union = typeof union;
|
|
59
|
+
//=> {a1(): void; b1(): void} | {a2(argA: string): void; b2(argB: string): void}
|
|
60
|
+
|
|
61
|
+
type Intersection = UnionToIntersection<Union>;
|
|
62
|
+
//=> {a1(): void; b1(): void; a2(argA: string): void; b2(argB: string): void}
|
|
63
|
+
```
|
|
64
|
+
|
|
65
|
+
@category Type
|
|
66
|
+
*/
|
|
67
|
+
type UnionToIntersection<Union> = (
|
|
68
|
+
// `extends unknown` is always going to be the case and is used to convert the
|
|
69
|
+
// `Union` into a [distributive conditional
|
|
70
|
+
// type](https://www.typescriptlang.org/docs/handbook/release-notes/typescript-2-8.html#distributive-conditional-types).
|
|
71
|
+
Union extends unknown
|
|
72
|
+
// The union type is used as the only argument to a function since the union
|
|
73
|
+
// of function arguments is an intersection.
|
|
74
|
+
? (distributedUnion: Union) => void
|
|
75
|
+
// This won't happen.
|
|
76
|
+
: never
|
|
77
|
+
// Infer the `Intersection` type since TypeScript represents the positional
|
|
78
|
+
// arguments of unions of functions as an intersection of the union.
|
|
79
|
+
) extends ((mergedIntersection: infer Intersection) => void)
|
|
80
|
+
// The `& Union` is to allow indexing by the resulting type
|
|
81
|
+
? Intersection & Union
|
|
82
|
+
: never;
|
|
83
|
+
|
|
22
84
|
declare const emptyObjectSymbol: unique symbol;
|
|
23
85
|
|
|
24
86
|
/**
|
|
@@ -560,9 +622,11 @@ If `<Fill>` is not provided, it will default to `unknown`.
|
|
|
560
622
|
|
|
561
623
|
@link https://itnext.io/implementing-arithmetic-within-typescripts-type-system-a1ef140a6f6f
|
|
562
624
|
*/
|
|
563
|
-
type BuildTuple<L extends number, Fill = unknown, T extends readonly unknown[] = []> =
|
|
564
|
-
?
|
|
565
|
-
:
|
|
625
|
+
type BuildTuple<L extends number, Fill = unknown, T extends readonly unknown[] = []> = number extends L
|
|
626
|
+
? Fill[]
|
|
627
|
+
: L extends T['length']
|
|
628
|
+
? T
|
|
629
|
+
: BuildTuple<L, Fill, [...T, Fill]>;
|
|
566
630
|
|
|
567
631
|
/**
|
|
568
632
|
Returns the maximum value from a tuple of integers.
|
|
@@ -1337,68 +1401,6 @@ type InternalPaths<T, Options extends Required<PathsOptions>> =
|
|
|
1337
1401
|
: never
|
|
1338
1402
|
: never;
|
|
1339
1403
|
|
|
1340
|
-
/**
|
|
1341
|
-
Convert a union type to an intersection type using [distributive conditional types](https://www.typescriptlang.org/docs/handbook/release-notes/typescript-2-8.html#distributive-conditional-types).
|
|
1342
|
-
|
|
1343
|
-
Inspired by [this Stack Overflow answer](https://stackoverflow.com/a/50375286/2172153).
|
|
1344
|
-
|
|
1345
|
-
@example
|
|
1346
|
-
```
|
|
1347
|
-
import type {UnionToIntersection} from 'type-fest';
|
|
1348
|
-
|
|
1349
|
-
type Union = {the(): void} | {great(arg: string): void} | {escape: boolean};
|
|
1350
|
-
|
|
1351
|
-
type Intersection = UnionToIntersection<Union>;
|
|
1352
|
-
//=> {the(): void; great(arg: string): void; escape: boolean};
|
|
1353
|
-
```
|
|
1354
|
-
|
|
1355
|
-
A more applicable example which could make its way into your library code follows.
|
|
1356
|
-
|
|
1357
|
-
@example
|
|
1358
|
-
```
|
|
1359
|
-
import type {UnionToIntersection} from 'type-fest';
|
|
1360
|
-
|
|
1361
|
-
class CommandOne {
|
|
1362
|
-
commands: {
|
|
1363
|
-
a1: () => undefined,
|
|
1364
|
-
b1: () => undefined,
|
|
1365
|
-
}
|
|
1366
|
-
}
|
|
1367
|
-
|
|
1368
|
-
class CommandTwo {
|
|
1369
|
-
commands: {
|
|
1370
|
-
a2: (argA: string) => undefined,
|
|
1371
|
-
b2: (argB: string) => undefined,
|
|
1372
|
-
}
|
|
1373
|
-
}
|
|
1374
|
-
|
|
1375
|
-
const union = [new CommandOne(), new CommandTwo()].map(instance => instance.commands);
|
|
1376
|
-
type Union = typeof union;
|
|
1377
|
-
//=> {a1(): void; b1(): void} | {a2(argA: string): void; b2(argB: string): void}
|
|
1378
|
-
|
|
1379
|
-
type Intersection = UnionToIntersection<Union>;
|
|
1380
|
-
//=> {a1(): void; b1(): void; a2(argA: string): void; b2(argB: string): void}
|
|
1381
|
-
```
|
|
1382
|
-
|
|
1383
|
-
@category Type
|
|
1384
|
-
*/
|
|
1385
|
-
type UnionToIntersection<Union> = (
|
|
1386
|
-
// `extends unknown` is always going to be the case and is used to convert the
|
|
1387
|
-
// `Union` into a [distributive conditional
|
|
1388
|
-
// type](https://www.typescriptlang.org/docs/handbook/release-notes/typescript-2-8.html#distributive-conditional-types).
|
|
1389
|
-
Union extends unknown
|
|
1390
|
-
// The union type is used as the only argument to a function since the union
|
|
1391
|
-
// of function arguments is an intersection.
|
|
1392
|
-
? (distributedUnion: Union) => void
|
|
1393
|
-
// This won't happen.
|
|
1394
|
-
: never
|
|
1395
|
-
// Infer the `Intersection` type since TypeScript represents the positional
|
|
1396
|
-
// arguments of unions of functions as an intersection of the union.
|
|
1397
|
-
) extends ((mergedIntersection: infer Intersection) => void)
|
|
1398
|
-
// The `& Union` is to allow indexing by the resulting type
|
|
1399
|
-
? Intersection & Union
|
|
1400
|
-
: never;
|
|
1401
|
-
|
|
1402
1404
|
/**
|
|
1403
1405
|
Pick properties from a deeply-nested object.
|
|
1404
1406
|
|
|
@@ -2040,11 +2042,17 @@ array = split(items, ',');
|
|
|
2040
2042
|
type Split<
|
|
2041
2043
|
S extends string,
|
|
2042
2044
|
Delimiter extends string,
|
|
2045
|
+
> = SplitHelper<S, Delimiter>;
|
|
2046
|
+
|
|
2047
|
+
type SplitHelper<
|
|
2048
|
+
S extends string,
|
|
2049
|
+
Delimiter extends string,
|
|
2050
|
+
Accumulator extends string[] = [],
|
|
2043
2051
|
> = S extends `${infer Head}${Delimiter}${infer Tail}`
|
|
2044
|
-
?
|
|
2045
|
-
:
|
|
2046
|
-
?
|
|
2047
|
-
: [S];
|
|
2052
|
+
? SplitHelper<Tail, Delimiter, [...Accumulator, Head]>
|
|
2053
|
+
: Delimiter extends ''
|
|
2054
|
+
? Accumulator
|
|
2055
|
+
: [...Accumulator, S];
|
|
2048
2056
|
|
|
2049
2057
|
type GetOptions = {
|
|
2050
2058
|
/**
|
|
@@ -2247,7 +2255,7 @@ type Get<
|
|
|
2247
2255
|
BaseType,
|
|
2248
2256
|
Path extends
|
|
2249
2257
|
| readonly string[]
|
|
2250
|
-
| LiteralStringUnion<ToString<Paths<BaseType, {bracketNotation: false}> | Paths<BaseType, {bracketNotation: true}>>>,
|
|
2258
|
+
| LiteralStringUnion<ToString<Paths<BaseType, {bracketNotation: false; maxRecursionDepth: 2}> | Paths<BaseType, {bracketNotation: true; maxRecursionDepth: 2}>>>,
|
|
2251
2259
|
Options extends GetOptions = {}> =
|
|
2252
2260
|
GetWithPath<BaseType, Path extends string ? ToPath<Path> : Path, Options>;
|
|
2253
2261
|
|
package/dist/index.d.ts
CHANGED
|
@@ -19,6 +19,68 @@ declare global {
|
|
|
19
19
|
}
|
|
20
20
|
}
|
|
21
21
|
|
|
22
|
+
/**
|
|
23
|
+
Convert a union type to an intersection type using [distributive conditional types](https://www.typescriptlang.org/docs/handbook/release-notes/typescript-2-8.html#distributive-conditional-types).
|
|
24
|
+
|
|
25
|
+
Inspired by [this Stack Overflow answer](https://stackoverflow.com/a/50375286/2172153).
|
|
26
|
+
|
|
27
|
+
@example
|
|
28
|
+
```
|
|
29
|
+
import type {UnionToIntersection} from 'type-fest';
|
|
30
|
+
|
|
31
|
+
type Union = {the(): void} | {great(arg: string): void} | {escape: boolean};
|
|
32
|
+
|
|
33
|
+
type Intersection = UnionToIntersection<Union>;
|
|
34
|
+
//=> {the(): void; great(arg: string): void; escape: boolean};
|
|
35
|
+
```
|
|
36
|
+
|
|
37
|
+
A more applicable example which could make its way into your library code follows.
|
|
38
|
+
|
|
39
|
+
@example
|
|
40
|
+
```
|
|
41
|
+
import type {UnionToIntersection} from 'type-fest';
|
|
42
|
+
|
|
43
|
+
class CommandOne {
|
|
44
|
+
commands: {
|
|
45
|
+
a1: () => undefined,
|
|
46
|
+
b1: () => undefined,
|
|
47
|
+
}
|
|
48
|
+
}
|
|
49
|
+
|
|
50
|
+
class CommandTwo {
|
|
51
|
+
commands: {
|
|
52
|
+
a2: (argA: string) => undefined,
|
|
53
|
+
b2: (argB: string) => undefined,
|
|
54
|
+
}
|
|
55
|
+
}
|
|
56
|
+
|
|
57
|
+
const union = [new CommandOne(), new CommandTwo()].map(instance => instance.commands);
|
|
58
|
+
type Union = typeof union;
|
|
59
|
+
//=> {a1(): void; b1(): void} | {a2(argA: string): void; b2(argB: string): void}
|
|
60
|
+
|
|
61
|
+
type Intersection = UnionToIntersection<Union>;
|
|
62
|
+
//=> {a1(): void; b1(): void; a2(argA: string): void; b2(argB: string): void}
|
|
63
|
+
```
|
|
64
|
+
|
|
65
|
+
@category Type
|
|
66
|
+
*/
|
|
67
|
+
type UnionToIntersection<Union> = (
|
|
68
|
+
// `extends unknown` is always going to be the case and is used to convert the
|
|
69
|
+
// `Union` into a [distributive conditional
|
|
70
|
+
// type](https://www.typescriptlang.org/docs/handbook/release-notes/typescript-2-8.html#distributive-conditional-types).
|
|
71
|
+
Union extends unknown
|
|
72
|
+
// The union type is used as the only argument to a function since the union
|
|
73
|
+
// of function arguments is an intersection.
|
|
74
|
+
? (distributedUnion: Union) => void
|
|
75
|
+
// This won't happen.
|
|
76
|
+
: never
|
|
77
|
+
// Infer the `Intersection` type since TypeScript represents the positional
|
|
78
|
+
// arguments of unions of functions as an intersection of the union.
|
|
79
|
+
) extends ((mergedIntersection: infer Intersection) => void)
|
|
80
|
+
// The `& Union` is to allow indexing by the resulting type
|
|
81
|
+
? Intersection & Union
|
|
82
|
+
: never;
|
|
83
|
+
|
|
22
84
|
declare const emptyObjectSymbol: unique symbol;
|
|
23
85
|
|
|
24
86
|
/**
|
|
@@ -560,9 +622,11 @@ If `<Fill>` is not provided, it will default to `unknown`.
|
|
|
560
622
|
|
|
561
623
|
@link https://itnext.io/implementing-arithmetic-within-typescripts-type-system-a1ef140a6f6f
|
|
562
624
|
*/
|
|
563
|
-
type BuildTuple<L extends number, Fill = unknown, T extends readonly unknown[] = []> =
|
|
564
|
-
?
|
|
565
|
-
:
|
|
625
|
+
type BuildTuple<L extends number, Fill = unknown, T extends readonly unknown[] = []> = number extends L
|
|
626
|
+
? Fill[]
|
|
627
|
+
: L extends T['length']
|
|
628
|
+
? T
|
|
629
|
+
: BuildTuple<L, Fill, [...T, Fill]>;
|
|
566
630
|
|
|
567
631
|
/**
|
|
568
632
|
Returns the maximum value from a tuple of integers.
|
|
@@ -1337,68 +1401,6 @@ type InternalPaths<T, Options extends Required<PathsOptions>> =
|
|
|
1337
1401
|
: never
|
|
1338
1402
|
: never;
|
|
1339
1403
|
|
|
1340
|
-
/**
|
|
1341
|
-
Convert a union type to an intersection type using [distributive conditional types](https://www.typescriptlang.org/docs/handbook/release-notes/typescript-2-8.html#distributive-conditional-types).
|
|
1342
|
-
|
|
1343
|
-
Inspired by [this Stack Overflow answer](https://stackoverflow.com/a/50375286/2172153).
|
|
1344
|
-
|
|
1345
|
-
@example
|
|
1346
|
-
```
|
|
1347
|
-
import type {UnionToIntersection} from 'type-fest';
|
|
1348
|
-
|
|
1349
|
-
type Union = {the(): void} | {great(arg: string): void} | {escape: boolean};
|
|
1350
|
-
|
|
1351
|
-
type Intersection = UnionToIntersection<Union>;
|
|
1352
|
-
//=> {the(): void; great(arg: string): void; escape: boolean};
|
|
1353
|
-
```
|
|
1354
|
-
|
|
1355
|
-
A more applicable example which could make its way into your library code follows.
|
|
1356
|
-
|
|
1357
|
-
@example
|
|
1358
|
-
```
|
|
1359
|
-
import type {UnionToIntersection} from 'type-fest';
|
|
1360
|
-
|
|
1361
|
-
class CommandOne {
|
|
1362
|
-
commands: {
|
|
1363
|
-
a1: () => undefined,
|
|
1364
|
-
b1: () => undefined,
|
|
1365
|
-
}
|
|
1366
|
-
}
|
|
1367
|
-
|
|
1368
|
-
class CommandTwo {
|
|
1369
|
-
commands: {
|
|
1370
|
-
a2: (argA: string) => undefined,
|
|
1371
|
-
b2: (argB: string) => undefined,
|
|
1372
|
-
}
|
|
1373
|
-
}
|
|
1374
|
-
|
|
1375
|
-
const union = [new CommandOne(), new CommandTwo()].map(instance => instance.commands);
|
|
1376
|
-
type Union = typeof union;
|
|
1377
|
-
//=> {a1(): void; b1(): void} | {a2(argA: string): void; b2(argB: string): void}
|
|
1378
|
-
|
|
1379
|
-
type Intersection = UnionToIntersection<Union>;
|
|
1380
|
-
//=> {a1(): void; b1(): void; a2(argA: string): void; b2(argB: string): void}
|
|
1381
|
-
```
|
|
1382
|
-
|
|
1383
|
-
@category Type
|
|
1384
|
-
*/
|
|
1385
|
-
type UnionToIntersection<Union> = (
|
|
1386
|
-
// `extends unknown` is always going to be the case and is used to convert the
|
|
1387
|
-
// `Union` into a [distributive conditional
|
|
1388
|
-
// type](https://www.typescriptlang.org/docs/handbook/release-notes/typescript-2-8.html#distributive-conditional-types).
|
|
1389
|
-
Union extends unknown
|
|
1390
|
-
// The union type is used as the only argument to a function since the union
|
|
1391
|
-
// of function arguments is an intersection.
|
|
1392
|
-
? (distributedUnion: Union) => void
|
|
1393
|
-
// This won't happen.
|
|
1394
|
-
: never
|
|
1395
|
-
// Infer the `Intersection` type since TypeScript represents the positional
|
|
1396
|
-
// arguments of unions of functions as an intersection of the union.
|
|
1397
|
-
) extends ((mergedIntersection: infer Intersection) => void)
|
|
1398
|
-
// The `& Union` is to allow indexing by the resulting type
|
|
1399
|
-
? Intersection & Union
|
|
1400
|
-
: never;
|
|
1401
|
-
|
|
1402
1404
|
/**
|
|
1403
1405
|
Pick properties from a deeply-nested object.
|
|
1404
1406
|
|
|
@@ -2040,11 +2042,17 @@ array = split(items, ',');
|
|
|
2040
2042
|
type Split<
|
|
2041
2043
|
S extends string,
|
|
2042
2044
|
Delimiter extends string,
|
|
2045
|
+
> = SplitHelper<S, Delimiter>;
|
|
2046
|
+
|
|
2047
|
+
type SplitHelper<
|
|
2048
|
+
S extends string,
|
|
2049
|
+
Delimiter extends string,
|
|
2050
|
+
Accumulator extends string[] = [],
|
|
2043
2051
|
> = S extends `${infer Head}${Delimiter}${infer Tail}`
|
|
2044
|
-
?
|
|
2045
|
-
:
|
|
2046
|
-
?
|
|
2047
|
-
: [S];
|
|
2052
|
+
? SplitHelper<Tail, Delimiter, [...Accumulator, Head]>
|
|
2053
|
+
: Delimiter extends ''
|
|
2054
|
+
? Accumulator
|
|
2055
|
+
: [...Accumulator, S];
|
|
2048
2056
|
|
|
2049
2057
|
type GetOptions = {
|
|
2050
2058
|
/**
|
|
@@ -2247,7 +2255,7 @@ type Get<
|
|
|
2247
2255
|
BaseType,
|
|
2248
2256
|
Path extends
|
|
2249
2257
|
| readonly string[]
|
|
2250
|
-
| LiteralStringUnion<ToString<Paths<BaseType, {bracketNotation: false}> | Paths<BaseType, {bracketNotation: true}>>>,
|
|
2258
|
+
| LiteralStringUnion<ToString<Paths<BaseType, {bracketNotation: false; maxRecursionDepth: 2}> | Paths<BaseType, {bracketNotation: true; maxRecursionDepth: 2}>>>,
|
|
2251
2259
|
Options extends GetOptions = {}> =
|
|
2252
2260
|
GetWithPath<BaseType, Path extends string ? ToPath<Path> : Path, Options>;
|
|
2253
2261
|
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@visulima/object",
|
|
3
|
-
"version": "1.0.
|
|
3
|
+
"version": "1.0.9",
|
|
4
4
|
"description": "Helper functions for working with objects and arrays.",
|
|
5
5
|
"keywords": [
|
|
6
6
|
"visulima",
|
|
@@ -76,77 +76,11 @@
|
|
|
76
76
|
"README.md",
|
|
77
77
|
"CHANGELOG.md"
|
|
78
78
|
],
|
|
79
|
-
"devDependencies": {
|
|
80
|
-
"@anolilab/eslint-config": "^15.0.3",
|
|
81
|
-
"@anolilab/prettier-config": "^5.0.14",
|
|
82
|
-
"@anolilab/semantic-release-pnpm": "1.1.6",
|
|
83
|
-
"@anolilab/semantic-release-preset": "^9.0.3",
|
|
84
|
-
"@arethetypeswrong/cli": "^0.17.2",
|
|
85
|
-
"@babel/core": "^7.26.0",
|
|
86
|
-
"@rushstack/eslint-plugin-security": "^0.8.3",
|
|
87
|
-
"@secretlint/secretlint-rule-preset-recommend": "^9.0.0",
|
|
88
|
-
"@total-typescript/ts-reset": "^0.6.1",
|
|
89
|
-
"@types/node": "18.19.39",
|
|
90
|
-
"@visulima/packem": "^1.10.7",
|
|
91
|
-
"@vitest/coverage-v8": "^2.1.8",
|
|
92
|
-
"@vitest/ui": "^2.1.8",
|
|
93
|
-
"conventional-changelog-conventionalcommits": "8.0.0",
|
|
94
|
-
"cross-env": "^7.0.3",
|
|
95
|
-
"deeks": "^3.1.1",
|
|
96
|
-
"dot-prop": "^9.0.0",
|
|
97
|
-
"esbuild": "0.24.2",
|
|
98
|
-
"eslint": "8.57.0",
|
|
99
|
-
"eslint-plugin-deprecation": "^3.0.0",
|
|
100
|
-
"eslint-plugin-etc": "^2.0.3",
|
|
101
|
-
"eslint-plugin-import": "npm:eslint-plugin-i@^2.29.1",
|
|
102
|
-
"eslint-plugin-mdx": "^3.1.5",
|
|
103
|
-
"eslint-plugin-vitest": "0.4.1",
|
|
104
|
-
"eslint-plugin-vitest-globals": "^1.5.0",
|
|
105
|
-
"filter-obj": "^6.1.0",
|
|
106
|
-
"is-plain-obj": "^4.1.0",
|
|
107
|
-
"prettier": "^3.4.2",
|
|
108
|
-
"rimraf": "6.0.1",
|
|
109
|
-
"secretlint": "9.0.0",
|
|
110
|
-
"semantic-release": "^24.2.1",
|
|
111
|
-
"type-fest": "^4.32.0",
|
|
112
|
-
"typescript": "5.7.3",
|
|
113
|
-
"vitest": "^2.1.8"
|
|
114
|
-
},
|
|
115
79
|
"engines": {
|
|
116
|
-
"node": ">=18
|
|
80
|
+
"node": ">=18.0.0 <=23.x"
|
|
117
81
|
},
|
|
118
82
|
"publishConfig": {
|
|
119
83
|
"access": "public",
|
|
120
84
|
"provenance": true
|
|
121
|
-
},
|
|
122
|
-
"anolilab": {
|
|
123
|
-
"eslint-config": {
|
|
124
|
-
"plugin": {
|
|
125
|
-
"tsdoc": false,
|
|
126
|
-
"etc": false
|
|
127
|
-
},
|
|
128
|
-
"warn_on_unsupported_typescript_version": false,
|
|
129
|
-
"info_on_disabling_jsx_react_rule": false,
|
|
130
|
-
"info_on_disabling_prettier_conflict_rule": false,
|
|
131
|
-
"info_on_disabling_jsonc_sort_keys_rule": false,
|
|
132
|
-
"info_on_disabling_etc_no_deprecated": false
|
|
133
|
-
}
|
|
134
|
-
},
|
|
135
|
-
"scripts": {
|
|
136
|
-
"build": "cross-env NODE_ENV=development packem build",
|
|
137
|
-
"build:prod": "cross-env NODE_ENV=production packem build",
|
|
138
|
-
"clean": "rimraf node_modules dist .eslintcache",
|
|
139
|
-
"dev": "pnpm run build --watch",
|
|
140
|
-
"lint:attw": "attw --pack",
|
|
141
|
-
"lint:eslint": "eslint . --ext js,cjs,mjs,jsx,ts,tsx,json,yaml,yml,md,mdx --max-warnings=0 --config .eslintrc.cjs",
|
|
142
|
-
"lint:eslint:fix": "eslint . --ext js,cjs,mjs,jsx,ts,tsx,json,yaml,yml,md,mdx --max-warnings=0 --config .eslintrc.cjs --fix",
|
|
143
|
-
"lint:package-json": "publint --strict",
|
|
144
|
-
"lint:prettier": "prettier --config=.prettierrc.cjs --check .",
|
|
145
|
-
"lint:prettier:fix": "prettier --config=.prettierrc.cjs --write .",
|
|
146
|
-
"lint:types": "tsc --noEmit",
|
|
147
|
-
"test": "vitest run",
|
|
148
|
-
"test:coverage": "vitest run --coverage",
|
|
149
|
-
"test:ui": "vitest --ui --coverage.enabled=true",
|
|
150
|
-
"test:watch": "vitest"
|
|
151
85
|
}
|
|
152
86
|
}
|