@visulima/object 1.0.7 → 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 +22 -0
- package/README.md +1 -1
- package/dist/index.cjs +187 -1
- package/dist/index.d.cts +147 -116
- package/dist/index.d.mts +147 -116
- package/dist/index.d.ts +147 -116
- package/dist/index.mjs +176 -1
- package/dist/packem_shared/getProperty-BuSUBWTY.cjs +278 -0
- package/dist/packem_shared/getProperty-CqSBQFGO.mjs +269 -0
- package/dist/packem_shared/isPlainObject-BEp1xndO.mjs +12 -0
- package/dist/packem_shared/isPlainObject-D2hOGcuW.cjs +14 -0
- package/dist/packem_shared/omit-Bz46-jv-.mjs +38 -0
- package/dist/packem_shared/omit-DSwyUtN2.cjs +40 -0
- package/dist/packem_shared/paths-are-equal-BvHTDEDJ.cjs +15 -0
- package/dist/packem_shared/paths-are-equal-DY1QWTwZ.mjs +13 -0
- package/dist/packem_shared/pick-BX11mP2m.cjs +52 -0
- package/dist/packem_shared/pick-C9-E3eDJ.mjs +50 -0
- package/package.json +2 -68
- package/dist/packem_shared/getProperty-Crh_HruK.cjs +0 -1
- package/dist/packem_shared/getProperty-D2xQpEOY.mjs +0 -1
- package/dist/packem_shared/isPlainObject-CLTs8VdF.mjs +0 -1
- package/dist/packem_shared/isPlainObject-Ct8-08mJ.cjs +0 -1
- package/dist/packem_shared/omit-BQOPjoaX.cjs +0 -1
- package/dist/packem_shared/omit-BcaD2qRn.mjs +0 -1
- package/dist/packem_shared/paths-are-equal-BgwMgI_D.mjs +0 -1
- package/dist/packem_shared/paths-are-equal-D8teV-Y-.cjs +0 -1
- package/dist/packem_shared/pick-BxgLK1bH.mjs +0 -1
- package/dist/packem_shared/pick-fC8KqJig.cjs +0 -1
package/CHANGELOG.md
CHANGED
|
@@ -1,3 +1,25 @@
|
|
|
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
|
+
|
|
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)
|
|
14
|
+
|
|
15
|
+
### Bug Fixes
|
|
16
|
+
|
|
17
|
+
* updated @visulima/packem, and all other dev dependencies ([7797a1c](https://github.com/visulima/visulima/commit/7797a1c3e6f1fc532895247bd88285a8a9883c40))
|
|
18
|
+
|
|
19
|
+
### Miscellaneous Chores
|
|
20
|
+
|
|
21
|
+
* updated dev dependencies ([9de2eab](https://github.com/visulima/visulima/commit/9de2eab91e95c8b9289d12f863a5167218770650))
|
|
22
|
+
|
|
1
23
|
## @visulima/object [1.0.7](https://github.com/visulima/visulima/compare/@visulima/object@1.0.6...@visulima/object@1.0.7) (2024-12-12)
|
|
2
24
|
|
|
3
25
|
### 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.cjs
CHANGED
|
@@ -1 +1,187 @@
|
|
|
1
|
-
|
|
1
|
+
'use strict';
|
|
2
|
+
|
|
3
|
+
Object.defineProperties(exports, { __esModule: { value: true }, [Symbol.toStringTag]: { value: 'Module' } });
|
|
4
|
+
|
|
5
|
+
const omit = require('./packem_shared/omit-DSwyUtN2.cjs');
|
|
6
|
+
const pick = require('./packem_shared/pick-BX11mP2m.cjs');
|
|
7
|
+
const getProperty = require('./packem_shared/getProperty-BuSUBWTY.cjs');
|
|
8
|
+
const isPlainObject = require('./packem_shared/isPlainObject-D2hOGcuW.cjs');
|
|
9
|
+
|
|
10
|
+
var deeks = {};
|
|
11
|
+
|
|
12
|
+
var utils = {};
|
|
13
|
+
|
|
14
|
+
var hasRequiredUtils;
|
|
15
|
+
|
|
16
|
+
function requireUtils () {
|
|
17
|
+
if (hasRequiredUtils) return utils;
|
|
18
|
+
hasRequiredUtils = 1;
|
|
19
|
+
var __defProp = Object.defineProperty;
|
|
20
|
+
var __name = (target, value) => __defProp(target, "name", { value, configurable: true });
|
|
21
|
+
Object.defineProperty(utils, "__esModule", { value: true });
|
|
22
|
+
utils.isDocumentToRecurOn = utils.flatten = utils.unique = undefined;
|
|
23
|
+
function unique(array) {
|
|
24
|
+
return [...new Set(array)];
|
|
25
|
+
}
|
|
26
|
+
__name(unique, "unique");
|
|
27
|
+
utils.unique = unique;
|
|
28
|
+
function flatten(array) {
|
|
29
|
+
return [].concat(...array);
|
|
30
|
+
}
|
|
31
|
+
__name(flatten, "flatten");
|
|
32
|
+
utils.flatten = flatten;
|
|
33
|
+
function isDocumentToRecurOn(val) {
|
|
34
|
+
return typeof val === "object" && val !== null && !Array.isArray(val) && Object.keys(val).length;
|
|
35
|
+
}
|
|
36
|
+
__name(isDocumentToRecurOn, "isDocumentToRecurOn");
|
|
37
|
+
utils.isDocumentToRecurOn = isDocumentToRecurOn;
|
|
38
|
+
return utils;
|
|
39
|
+
}
|
|
40
|
+
|
|
41
|
+
var types = {};
|
|
42
|
+
|
|
43
|
+
var hasRequiredTypes;
|
|
44
|
+
|
|
45
|
+
function requireTypes () {
|
|
46
|
+
if (hasRequiredTypes) return types;
|
|
47
|
+
hasRequiredTypes = 1;
|
|
48
|
+
Object.defineProperty(types, "__esModule", { value: true });
|
|
49
|
+
return types;
|
|
50
|
+
}
|
|
51
|
+
|
|
52
|
+
var hasRequiredDeeks;
|
|
53
|
+
|
|
54
|
+
function requireDeeks () {
|
|
55
|
+
if (hasRequiredDeeks) return deeks;
|
|
56
|
+
hasRequiredDeeks = 1;
|
|
57
|
+
(function (exports) {
|
|
58
|
+
var __defProp = Object.defineProperty;
|
|
59
|
+
var __name = (target, value) => __defProp(target, "name", { value, configurable: true });
|
|
60
|
+
var __createBinding = deeks.__createBinding || (Object.create ? function(o, m, k, k2) {
|
|
61
|
+
if (k2 === undefined) k2 = k;
|
|
62
|
+
var desc = Object.getOwnPropertyDescriptor(m, k);
|
|
63
|
+
if (!desc || ("get" in desc ? !m.__esModule : desc.writable || desc.configurable)) {
|
|
64
|
+
desc = { enumerable: true, get: /* @__PURE__ */ __name(function() {
|
|
65
|
+
return m[k];
|
|
66
|
+
}, "get") };
|
|
67
|
+
}
|
|
68
|
+
Object.defineProperty(o, k2, desc);
|
|
69
|
+
} : function(o, m, k, k2) {
|
|
70
|
+
if (k2 === undefined) k2 = k;
|
|
71
|
+
o[k2] = m[k];
|
|
72
|
+
});
|
|
73
|
+
var __setModuleDefault = deeks.__setModuleDefault || (Object.create ? function(o, v) {
|
|
74
|
+
Object.defineProperty(o, "default", { enumerable: true, value: v });
|
|
75
|
+
} : function(o, v) {
|
|
76
|
+
o["default"] = v;
|
|
77
|
+
});
|
|
78
|
+
var __importStar = deeks.__importStar || function(mod) {
|
|
79
|
+
if (mod && mod.__esModule) return mod;
|
|
80
|
+
var result = {};
|
|
81
|
+
if (mod != null) {
|
|
82
|
+
for (var k in mod) if (k !== "default" && Object.prototype.hasOwnProperty.call(mod, k)) __createBinding(result, mod, k);
|
|
83
|
+
}
|
|
84
|
+
__setModuleDefault(result, mod);
|
|
85
|
+
return result;
|
|
86
|
+
};
|
|
87
|
+
var __exportStar = deeks.__exportStar || function(m, exports2) {
|
|
88
|
+
for (var p in m) if (p !== "default" && !Object.prototype.hasOwnProperty.call(exports2, p)) __createBinding(exports2, m, p);
|
|
89
|
+
};
|
|
90
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
91
|
+
exports.deepKeysFromList = exports.deepKeys = undefined;
|
|
92
|
+
const utils = __importStar(requireUtils());
|
|
93
|
+
__exportStar(requireTypes(), exports);
|
|
94
|
+
function deepKeys(object, options) {
|
|
95
|
+
const parsedOptions = mergeOptions(options);
|
|
96
|
+
if (typeof object === "object" && object !== null) {
|
|
97
|
+
return generateDeepKeysList("", object, parsedOptions);
|
|
98
|
+
}
|
|
99
|
+
return [];
|
|
100
|
+
}
|
|
101
|
+
__name(deepKeys, "deepKeys");
|
|
102
|
+
exports.deepKeys = deepKeys;
|
|
103
|
+
function deepKeysFromList(list, options) {
|
|
104
|
+
const parsedOptions = mergeOptions(options);
|
|
105
|
+
return list.map((document) => {
|
|
106
|
+
if (typeof document === "object" && document !== null) {
|
|
107
|
+
return deepKeys(document, parsedOptions);
|
|
108
|
+
}
|
|
109
|
+
return [];
|
|
110
|
+
});
|
|
111
|
+
}
|
|
112
|
+
__name(deepKeysFromList, "deepKeysFromList");
|
|
113
|
+
exports.deepKeysFromList = deepKeysFromList;
|
|
114
|
+
function generateDeepKeysList(heading, data, options) {
|
|
115
|
+
const keys = Object.keys(data).map((currentKey) => {
|
|
116
|
+
const keyName = buildKeyName(heading, escapeNestedDotsIfSpecified(currentKey, options));
|
|
117
|
+
if (options.expandNestedObjects && utils.isDocumentToRecurOn(data[currentKey]) || options.arrayIndexesAsKeys && Array.isArray(data[currentKey]) && data[currentKey].length) {
|
|
118
|
+
return generateDeepKeysList(keyName, data[currentKey], options);
|
|
119
|
+
} else if (options.expandArrayObjects && Array.isArray(data[currentKey])) {
|
|
120
|
+
return processArrayKeys(data[currentKey], keyName, options);
|
|
121
|
+
} else if (options.ignoreEmptyArrays && Array.isArray(data[currentKey]) && !data[currentKey].length) {
|
|
122
|
+
return [];
|
|
123
|
+
}
|
|
124
|
+
return keyName;
|
|
125
|
+
});
|
|
126
|
+
return utils.flatten(keys);
|
|
127
|
+
}
|
|
128
|
+
__name(generateDeepKeysList, "generateDeepKeysList");
|
|
129
|
+
function processArrayKeys(subArray, currentKeyPath, options) {
|
|
130
|
+
let subArrayKeys = deepKeysFromList(subArray, options);
|
|
131
|
+
if (!subArray.length) {
|
|
132
|
+
return options.ignoreEmptyArraysWhenExpanding ? [] : [currentKeyPath];
|
|
133
|
+
} else if (subArray.length && utils.flatten(subArrayKeys).length === 0) {
|
|
134
|
+
return [currentKeyPath];
|
|
135
|
+
} else {
|
|
136
|
+
subArrayKeys = subArrayKeys.map((schemaKeys) => {
|
|
137
|
+
if (Array.isArray(schemaKeys) && schemaKeys.length === 0) {
|
|
138
|
+
return [currentKeyPath];
|
|
139
|
+
}
|
|
140
|
+
return schemaKeys.map((subKey) => buildKeyName(currentKeyPath, escapeNestedDotsIfSpecified(subKey, options)));
|
|
141
|
+
});
|
|
142
|
+
return utils.unique(utils.flatten(subArrayKeys));
|
|
143
|
+
}
|
|
144
|
+
}
|
|
145
|
+
__name(processArrayKeys, "processArrayKeys");
|
|
146
|
+
function escapeNestedDotsIfSpecified(key, options) {
|
|
147
|
+
if (options.escapeNestedDots) {
|
|
148
|
+
return key.replace(/\./g, "\\.");
|
|
149
|
+
}
|
|
150
|
+
return key;
|
|
151
|
+
}
|
|
152
|
+
__name(escapeNestedDotsIfSpecified, "escapeNestedDotsIfSpecified");
|
|
153
|
+
function buildKeyName(upperKeyName, currentKeyName) {
|
|
154
|
+
if (upperKeyName) {
|
|
155
|
+
return upperKeyName + "." + currentKeyName;
|
|
156
|
+
}
|
|
157
|
+
return currentKeyName;
|
|
158
|
+
}
|
|
159
|
+
__name(buildKeyName, "buildKeyName");
|
|
160
|
+
function mergeOptions(options) {
|
|
161
|
+
return {
|
|
162
|
+
arrayIndexesAsKeys: false,
|
|
163
|
+
expandNestedObjects: true,
|
|
164
|
+
expandArrayObjects: false,
|
|
165
|
+
ignoreEmptyArraysWhenExpanding: false,
|
|
166
|
+
escapeNestedDots: false,
|
|
167
|
+
ignoreEmptyArrays: false,
|
|
168
|
+
...options ?? {}
|
|
169
|
+
};
|
|
170
|
+
}
|
|
171
|
+
__name(mergeOptions, "mergeOptions");
|
|
172
|
+
} (deeks));
|
|
173
|
+
return deeks;
|
|
174
|
+
}
|
|
175
|
+
|
|
176
|
+
var deeksExports = requireDeeks();
|
|
177
|
+
|
|
178
|
+
exports.omit = omit;
|
|
179
|
+
exports.pick = pick;
|
|
180
|
+
exports.deleteProperty = getProperty.deleteProperty;
|
|
181
|
+
exports.escapePath = getProperty.escapePath;
|
|
182
|
+
exports.getProperty = getProperty.getProperty;
|
|
183
|
+
exports.hasProperty = getProperty.hasProperty;
|
|
184
|
+
exports.setProperty = getProperty.setProperty;
|
|
185
|
+
exports.isPlainObject = isPlainObject;
|
|
186
|
+
exports.deepKeys = deeksExports.deepKeys;
|
|
187
|
+
exports.deepKeysFromList = deeksExports.deepKeysFromList;
|
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
|
/**
|
|
@@ -76,8 +138,8 @@ type Includes<Value extends readonly any[], Item> =
|
|
|
76
138
|
@category Utilities
|
|
77
139
|
*/
|
|
78
140
|
type IsEqual<A, B> =
|
|
79
|
-
(<G>() => G extends A ? 1 : 2) extends
|
|
80
|
-
(<G>() => G extends B ? 1 : 2)
|
|
141
|
+
(<G>() => G extends A & G | G ? 1 : 2) extends
|
|
142
|
+
(<G>() => G extends B & G | G ? 1 : 2)
|
|
81
143
|
? true
|
|
82
144
|
: false;
|
|
83
145
|
|
|
@@ -166,6 +228,72 @@ fn(someInterface as Simplify<SomeInterface>); // Good: transform an `interface`
|
|
|
166
228
|
*/
|
|
167
229
|
type Simplify<T> = {[KeyType in keyof T]: T[KeyType]} & {};
|
|
168
230
|
|
|
231
|
+
/**
|
|
232
|
+
Returns a boolean for whether the given type is `never`.
|
|
233
|
+
|
|
234
|
+
@link https://github.com/microsoft/TypeScript/issues/31751#issuecomment-498526919
|
|
235
|
+
@link https://stackoverflow.com/a/53984913/10292952
|
|
236
|
+
@link https://www.zhenghao.io/posts/ts-never
|
|
237
|
+
|
|
238
|
+
Useful in type utilities, such as checking if something does not occur.
|
|
239
|
+
|
|
240
|
+
@example
|
|
241
|
+
```
|
|
242
|
+
import type {IsNever, And} from 'type-fest';
|
|
243
|
+
|
|
244
|
+
// https://github.com/andnp/SimplyTyped/blob/master/src/types/strings.ts
|
|
245
|
+
type AreStringsEqual<A extends string, B extends string> =
|
|
246
|
+
And<
|
|
247
|
+
IsNever<Exclude<A, B>> extends true ? true : false,
|
|
248
|
+
IsNever<Exclude<B, A>> extends true ? true : false
|
|
249
|
+
>;
|
|
250
|
+
|
|
251
|
+
type EndIfEqual<I extends string, O extends string> =
|
|
252
|
+
AreStringsEqual<I, O> extends true
|
|
253
|
+
? never
|
|
254
|
+
: void;
|
|
255
|
+
|
|
256
|
+
function endIfEqual<I extends string, O extends string>(input: I, output: O): EndIfEqual<I, O> {
|
|
257
|
+
if (input === output) {
|
|
258
|
+
process.exit(0);
|
|
259
|
+
}
|
|
260
|
+
}
|
|
261
|
+
|
|
262
|
+
endIfEqual('abc', 'abc');
|
|
263
|
+
//=> never
|
|
264
|
+
|
|
265
|
+
endIfEqual('abc', '123');
|
|
266
|
+
//=> void
|
|
267
|
+
```
|
|
268
|
+
|
|
269
|
+
@category Type Guard
|
|
270
|
+
@category Utilities
|
|
271
|
+
*/
|
|
272
|
+
type IsNever<T> = [T] extends [never] ? true : false;
|
|
273
|
+
|
|
274
|
+
/**
|
|
275
|
+
An if-else-like type that resolves depending on whether the given type is `never`.
|
|
276
|
+
|
|
277
|
+
@see {@link IsNever}
|
|
278
|
+
|
|
279
|
+
@example
|
|
280
|
+
```
|
|
281
|
+
import type {IfNever} from 'type-fest';
|
|
282
|
+
|
|
283
|
+
type ShouldBeTrue = IfNever<never>;
|
|
284
|
+
//=> true
|
|
285
|
+
|
|
286
|
+
type ShouldBeBar = IfNever<'not never', 'foo', 'bar'>;
|
|
287
|
+
//=> 'bar'
|
|
288
|
+
```
|
|
289
|
+
|
|
290
|
+
@category Type Guard
|
|
291
|
+
@category Utilities
|
|
292
|
+
*/
|
|
293
|
+
type IfNever<T, TypeIfNever = true, TypeIfNotNever = false> = (
|
|
294
|
+
IsNever<T> extends true ? TypeIfNever : TypeIfNotNever
|
|
295
|
+
);
|
|
296
|
+
|
|
169
297
|
/**
|
|
170
298
|
Returns the static, fixed-length portion of the given array, excluding variable-length parts.
|
|
171
299
|
|
|
@@ -227,7 +355,7 @@ T extends readonly [...infer U] ?
|
|
|
227
355
|
/**
|
|
228
356
|
Returns whether the given array `T` is readonly.
|
|
229
357
|
*/
|
|
230
|
-
type IsArrayReadonly<T extends UnknownArray> = T extends unknown[] ? false : true
|
|
358
|
+
type IsArrayReadonly<T extends UnknownArray> = IfNever<T, false, T extends unknown[] ? false : true>;
|
|
231
359
|
|
|
232
360
|
type StringDigit = '0' | '1' | '2' | '3' | '4' | '5' | '6' | '7' | '8' | '9';
|
|
233
361
|
|
|
@@ -324,49 +452,6 @@ type ShouldBeTrue = IsNegative<-1>;
|
|
|
324
452
|
*/
|
|
325
453
|
type IsNegative<T extends Numeric> = T extends Negative<T> ? true : false;
|
|
326
454
|
|
|
327
|
-
/**
|
|
328
|
-
Returns a boolean for whether the given type is `never`.
|
|
329
|
-
|
|
330
|
-
@link https://github.com/microsoft/TypeScript/issues/31751#issuecomment-498526919
|
|
331
|
-
@link https://stackoverflow.com/a/53984913/10292952
|
|
332
|
-
@link https://www.zhenghao.io/posts/ts-never
|
|
333
|
-
|
|
334
|
-
Useful in type utilities, such as checking if something does not occur.
|
|
335
|
-
|
|
336
|
-
@example
|
|
337
|
-
```
|
|
338
|
-
import type {IsNever, And} from 'type-fest';
|
|
339
|
-
|
|
340
|
-
// https://github.com/andnp/SimplyTyped/blob/master/src/types/strings.ts
|
|
341
|
-
type AreStringsEqual<A extends string, B extends string> =
|
|
342
|
-
And<
|
|
343
|
-
IsNever<Exclude<A, B>> extends true ? true : false,
|
|
344
|
-
IsNever<Exclude<B, A>> extends true ? true : false
|
|
345
|
-
>;
|
|
346
|
-
|
|
347
|
-
type EndIfEqual<I extends string, O extends string> =
|
|
348
|
-
AreStringsEqual<I, O> extends true
|
|
349
|
-
? never
|
|
350
|
-
: void;
|
|
351
|
-
|
|
352
|
-
function endIfEqual<I extends string, O extends string>(input: I, output: O): EndIfEqual<I, O> {
|
|
353
|
-
if (input === output) {
|
|
354
|
-
process.exit(0);
|
|
355
|
-
}
|
|
356
|
-
}
|
|
357
|
-
|
|
358
|
-
endIfEqual('abc', 'abc');
|
|
359
|
-
//=> never
|
|
360
|
-
|
|
361
|
-
endIfEqual('abc', '123');
|
|
362
|
-
//=> void
|
|
363
|
-
```
|
|
364
|
-
|
|
365
|
-
@category Type Guard
|
|
366
|
-
@category Utilities
|
|
367
|
-
*/
|
|
368
|
-
type IsNever<T> = [T] extends [never] ? true : false;
|
|
369
|
-
|
|
370
455
|
/**
|
|
371
456
|
Returns a boolean for whether two given types are both true.
|
|
372
457
|
|
|
@@ -537,9 +622,11 @@ If `<Fill>` is not provided, it will default to `unknown`.
|
|
|
537
622
|
|
|
538
623
|
@link https://itnext.io/implementing-arithmetic-within-typescripts-type-system-a1ef140a6f6f
|
|
539
624
|
*/
|
|
540
|
-
type BuildTuple<L extends number, Fill = unknown, T extends readonly unknown[] = []> =
|
|
541
|
-
?
|
|
542
|
-
:
|
|
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]>;
|
|
543
630
|
|
|
544
631
|
/**
|
|
545
632
|
Returns the maximum value from a tuple of integers.
|
|
@@ -1314,68 +1401,6 @@ type InternalPaths<T, Options extends Required<PathsOptions>> =
|
|
|
1314
1401
|
: never
|
|
1315
1402
|
: never;
|
|
1316
1403
|
|
|
1317
|
-
/**
|
|
1318
|
-
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).
|
|
1319
|
-
|
|
1320
|
-
Inspired by [this Stack Overflow answer](https://stackoverflow.com/a/50375286/2172153).
|
|
1321
|
-
|
|
1322
|
-
@example
|
|
1323
|
-
```
|
|
1324
|
-
import type {UnionToIntersection} from 'type-fest';
|
|
1325
|
-
|
|
1326
|
-
type Union = {the(): void} | {great(arg: string): void} | {escape: boolean};
|
|
1327
|
-
|
|
1328
|
-
type Intersection = UnionToIntersection<Union>;
|
|
1329
|
-
//=> {the(): void; great(arg: string): void; escape: boolean};
|
|
1330
|
-
```
|
|
1331
|
-
|
|
1332
|
-
A more applicable example which could make its way into your library code follows.
|
|
1333
|
-
|
|
1334
|
-
@example
|
|
1335
|
-
```
|
|
1336
|
-
import type {UnionToIntersection} from 'type-fest';
|
|
1337
|
-
|
|
1338
|
-
class CommandOne {
|
|
1339
|
-
commands: {
|
|
1340
|
-
a1: () => undefined,
|
|
1341
|
-
b1: () => undefined,
|
|
1342
|
-
}
|
|
1343
|
-
}
|
|
1344
|
-
|
|
1345
|
-
class CommandTwo {
|
|
1346
|
-
commands: {
|
|
1347
|
-
a2: (argA: string) => undefined,
|
|
1348
|
-
b2: (argB: string) => undefined,
|
|
1349
|
-
}
|
|
1350
|
-
}
|
|
1351
|
-
|
|
1352
|
-
const union = [new CommandOne(), new CommandTwo()].map(instance => instance.commands);
|
|
1353
|
-
type Union = typeof union;
|
|
1354
|
-
//=> {a1(): void; b1(): void} | {a2(argA: string): void; b2(argB: string): void}
|
|
1355
|
-
|
|
1356
|
-
type Intersection = UnionToIntersection<Union>;
|
|
1357
|
-
//=> {a1(): void; b1(): void; a2(argA: string): void; b2(argB: string): void}
|
|
1358
|
-
```
|
|
1359
|
-
|
|
1360
|
-
@category Type
|
|
1361
|
-
*/
|
|
1362
|
-
type UnionToIntersection<Union> = (
|
|
1363
|
-
// `extends unknown` is always going to be the case and is used to convert the
|
|
1364
|
-
// `Union` into a [distributive conditional
|
|
1365
|
-
// type](https://www.typescriptlang.org/docs/handbook/release-notes/typescript-2-8.html#distributive-conditional-types).
|
|
1366
|
-
Union extends unknown
|
|
1367
|
-
// The union type is used as the only argument to a function since the union
|
|
1368
|
-
// of function arguments is an intersection.
|
|
1369
|
-
? (distributedUnion: Union) => void
|
|
1370
|
-
// This won't happen.
|
|
1371
|
-
: never
|
|
1372
|
-
// Infer the `Intersection` type since TypeScript represents the positional
|
|
1373
|
-
// arguments of unions of functions as an intersection of the union.
|
|
1374
|
-
) extends ((mergedIntersection: infer Intersection) => void)
|
|
1375
|
-
// The `& Union` is to allow indexing by the resulting type
|
|
1376
|
-
? Intersection & Union
|
|
1377
|
-
: never;
|
|
1378
|
-
|
|
1379
1404
|
/**
|
|
1380
1405
|
Pick properties from a deeply-nested object.
|
|
1381
1406
|
|
|
@@ -2017,11 +2042,17 @@ array = split(items, ',');
|
|
|
2017
2042
|
type Split<
|
|
2018
2043
|
S extends string,
|
|
2019
2044
|
Delimiter extends string,
|
|
2045
|
+
> = SplitHelper<S, Delimiter>;
|
|
2046
|
+
|
|
2047
|
+
type SplitHelper<
|
|
2048
|
+
S extends string,
|
|
2049
|
+
Delimiter extends string,
|
|
2050
|
+
Accumulator extends string[] = [],
|
|
2020
2051
|
> = S extends `${infer Head}${Delimiter}${infer Tail}`
|
|
2021
|
-
?
|
|
2022
|
-
:
|
|
2023
|
-
?
|
|
2024
|
-
: [S];
|
|
2052
|
+
? SplitHelper<Tail, Delimiter, [...Accumulator, Head]>
|
|
2053
|
+
: Delimiter extends ''
|
|
2054
|
+
? Accumulator
|
|
2055
|
+
: [...Accumulator, S];
|
|
2025
2056
|
|
|
2026
2057
|
type GetOptions = {
|
|
2027
2058
|
/**
|
|
@@ -2224,7 +2255,7 @@ type Get<
|
|
|
2224
2255
|
BaseType,
|
|
2225
2256
|
Path extends
|
|
2226
2257
|
| readonly string[]
|
|
2227
|
-
| 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}>>>,
|
|
2228
2259
|
Options extends GetOptions = {}> =
|
|
2229
2260
|
GetWithPath<BaseType, Path extends string ? ToPath<Path> : Path, Options>;
|
|
2230
2261
|
|