@visulima/object 1.0.7 → 1.0.8

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 CHANGED
@@ -1,3 +1,13 @@
1
+ ## @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
+
3
+ ### Bug Fixes
4
+
5
+ * updated @visulima/packem, and all other dev dependencies ([7797a1c](https://github.com/visulima/visulima/commit/7797a1c3e6f1fc532895247bd88285a8a9883c40))
6
+
7
+ ### Miscellaneous Chores
8
+
9
+ * updated dev dependencies ([9de2eab](https://github.com/visulima/visulima/commit/9de2eab91e95c8b9289d12f863a5167218770650))
10
+
1
11
  ## @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
12
 
3
13
  ### Bug Fixes
package/dist/index.cjs CHANGED
@@ -1 +1,187 @@
1
- "use strict";var L=Object.defineProperty;var a=(c,p)=>L(c,"name",{value:p,configurable:!0});Object.defineProperty(exports,Symbol.toStringTag,{value:"Module"});const M=require("./packem_shared/omit-BQOPjoaX.cjs"),N=require("./packem_shared/pick-fC8KqJig.cjs"),b=require("./packem_shared/getProperty-Crh_HruK.cjs"),R=require("./packem_shared/isPlainObject-Ct8-08mJ.cjs");var s={},y={},D;function T(){if(D)return y;D=1;var c=Object.defineProperty,p=a((o,m)=>c(o,"name",{value:m,configurable:!0}),"t");Object.defineProperty(y,"__esModule",{value:!0}),y.isDocumentToRecurOn=y.flatten=y.unique=void 0;function u(o){return[...new Set(o)]}a(u,"unique"),p(u,"unique"),y.unique=u;function l(o){return[].concat(...o)}a(l,"flatten"),p(l,"flatten"),y.flatten=l;function g(o){return typeof o=="object"&&o!==null&&!Array.isArray(o)&&Object.keys(o).length}return a(g,"isDocumentToRecurOn"),p(g,"isDocumentToRecurOn"),y.isDocumentToRecurOn=g,y}a(T,"requireUtils");var K={},q;function E(){return q||(q=1,Object.defineProperty(K,"__esModule",{value:!0})),K}a(E,"requireTypes");var S;function x(){return S||(S=1,function(c){var p=Object.defineProperty,u=a((r,e)=>p(r,"name",{value:e,configurable:!0}),"i"),l=s&&s.__createBinding||(Object.create?function(r,e,t,i){i===void 0&&(i=t);var n=Object.getOwnPropertyDescriptor(e,t);(!n||("get"in n?!e.__esModule:n.writable||n.configurable))&&(n={enumerable:!0,get:u(function(){return e[t]},"get")}),Object.defineProperty(r,i,n)}:function(r,e,t,i){i===void 0&&(i=t),r[i]=e[t]}),g=s&&s.__setModuleDefault||(Object.create?function(r,e){Object.defineProperty(r,"default",{enumerable:!0,value:e})}:function(r,e){r.default=e}),o=s&&s.__importStar||function(r){if(r&&r.__esModule)return r;var e={};if(r!=null)for(var t in r)t!=="default"&&Object.prototype.hasOwnProperty.call(r,t)&&l(e,r,t);return g(e,r),e},m=s&&s.__exportStar||function(r,e){for(var t in r)t!=="default"&&!Object.prototype.hasOwnProperty.call(e,t)&&l(e,r,t)};Object.defineProperty(c,"__esModule",{value:!0}),c.deepKeysFromList=c.deepKeys=void 0;const d=o(T());m(E(),c);function O(r,e){const t=A(e);return typeof r=="object"&&r!==null?_("",r,t):[]}a(O,"deepKeys"),u(O,"deepKeys"),c.deepKeys=O;function v(r,e){const t=A(e);return r.map(i=>typeof i=="object"&&i!==null?O(i,t):[])}a(v,"deepKeysFromList"),u(v,"deepKeysFromList"),c.deepKeysFromList=v;function _(r,e,t){const i=Object.keys(e).map(n=>{const f=P(r,j(n,t));return t.expandNestedObjects&&d.isDocumentToRecurOn(e[n])||t.arrayIndexesAsKeys&&Array.isArray(e[n])&&e[n].length?_(f,e[n],t):t.expandArrayObjects&&Array.isArray(e[n])?h(e[n],f,t):t.ignoreEmptyArrays&&Array.isArray(e[n])&&!e[n].length?[]:f});return d.flatten(i)}a(_,"generateDeepKeysList"),u(_,"generateDeepKeysList");function h(r,e,t){let i=v(r,t);return r.length?r.length&&d.flatten(i).length===0?[e]:(i=i.map(n=>Array.isArray(n)&&n.length===0?[e]:n.map(f=>P(e,j(f,t)))),d.unique(d.flatten(i))):t.ignoreEmptyArraysWhenExpanding?[]:[e]}a(h,"processArrayKeys"),u(h,"processArrayKeys");function j(r,e){return e.escapeNestedDots?r.replace(/\./g,"\\."):r}a(j,"escapeNestedDotsIfSpecified"),u(j,"escapeNestedDotsIfSpecified");function P(r,e){return r?r+"."+e:e}a(P,"buildKeyName"),u(P,"buildKeyName");function A(r){return{arrayIndexesAsKeys:!1,expandNestedObjects:!0,expandArrayObjects:!1,ignoreEmptyArraysWhenExpanding:!1,escapeNestedDots:!1,ignoreEmptyArrays:!1,...r??{}}}a(A,"mergeOptions"),u(A,"mergeOptions")}(s)),s}a(x,"requireDeeks");var k=x();exports.omit=M;exports.pick=N;exports.deleteProperty=b.deleteProperty;exports.escapePath=b.escapePath;exports.getProperty=b.getProperty;exports.hasProperty=b.hasProperty;exports.setProperty=b.setProperty;exports.isPlainObject=R;exports.deepKeys=k.deepKeys;exports.deepKeysFromList=k.deepKeysFromList;
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
@@ -76,8 +76,8 @@ type Includes<Value extends readonly any[], Item> =
76
76
  @category Utilities
77
77
  */
78
78
  type IsEqual<A, B> =
79
- (<G>() => G extends A ? 1 : 2) extends
80
- (<G>() => G extends B ? 1 : 2)
79
+ (<G>() => G extends A & G | G ? 1 : 2) extends
80
+ (<G>() => G extends B & G | G ? 1 : 2)
81
81
  ? true
82
82
  : false;
83
83
 
@@ -166,6 +166,72 @@ fn(someInterface as Simplify<SomeInterface>); // Good: transform an `interface`
166
166
  */
167
167
  type Simplify<T> = {[KeyType in keyof T]: T[KeyType]} & {};
168
168
 
169
+ /**
170
+ Returns a boolean for whether the given type is `never`.
171
+
172
+ @link https://github.com/microsoft/TypeScript/issues/31751#issuecomment-498526919
173
+ @link https://stackoverflow.com/a/53984913/10292952
174
+ @link https://www.zhenghao.io/posts/ts-never
175
+
176
+ Useful in type utilities, such as checking if something does not occur.
177
+
178
+ @example
179
+ ```
180
+ import type {IsNever, And} from 'type-fest';
181
+
182
+ // https://github.com/andnp/SimplyTyped/blob/master/src/types/strings.ts
183
+ type AreStringsEqual<A extends string, B extends string> =
184
+ And<
185
+ IsNever<Exclude<A, B>> extends true ? true : false,
186
+ IsNever<Exclude<B, A>> extends true ? true : false
187
+ >;
188
+
189
+ type EndIfEqual<I extends string, O extends string> =
190
+ AreStringsEqual<I, O> extends true
191
+ ? never
192
+ : void;
193
+
194
+ function endIfEqual<I extends string, O extends string>(input: I, output: O): EndIfEqual<I, O> {
195
+ if (input === output) {
196
+ process.exit(0);
197
+ }
198
+ }
199
+
200
+ endIfEqual('abc', 'abc');
201
+ //=> never
202
+
203
+ endIfEqual('abc', '123');
204
+ //=> void
205
+ ```
206
+
207
+ @category Type Guard
208
+ @category Utilities
209
+ */
210
+ type IsNever<T> = [T] extends [never] ? true : false;
211
+
212
+ /**
213
+ An if-else-like type that resolves depending on whether the given type is `never`.
214
+
215
+ @see {@link IsNever}
216
+
217
+ @example
218
+ ```
219
+ import type {IfNever} from 'type-fest';
220
+
221
+ type ShouldBeTrue = IfNever<never>;
222
+ //=> true
223
+
224
+ type ShouldBeBar = IfNever<'not never', 'foo', 'bar'>;
225
+ //=> 'bar'
226
+ ```
227
+
228
+ @category Type Guard
229
+ @category Utilities
230
+ */
231
+ type IfNever<T, TypeIfNever = true, TypeIfNotNever = false> = (
232
+ IsNever<T> extends true ? TypeIfNever : TypeIfNotNever
233
+ );
234
+
169
235
  /**
170
236
  Returns the static, fixed-length portion of the given array, excluding variable-length parts.
171
237
 
@@ -227,7 +293,7 @@ T extends readonly [...infer U] ?
227
293
  /**
228
294
  Returns whether the given array `T` is readonly.
229
295
  */
230
- type IsArrayReadonly<T extends UnknownArray> = T extends unknown[] ? false : true;
296
+ type IsArrayReadonly<T extends UnknownArray> = IfNever<T, false, T extends unknown[] ? false : true>;
231
297
 
232
298
  type StringDigit = '0' | '1' | '2' | '3' | '4' | '5' | '6' | '7' | '8' | '9';
233
299
 
@@ -324,49 +390,6 @@ type ShouldBeTrue = IsNegative<-1>;
324
390
  */
325
391
  type IsNegative<T extends Numeric> = T extends Negative<T> ? true : false;
326
392
 
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
393
  /**
371
394
  Returns a boolean for whether two given types are both true.
372
395
 
package/dist/index.d.mts CHANGED
@@ -76,8 +76,8 @@ type Includes<Value extends readonly any[], Item> =
76
76
  @category Utilities
77
77
  */
78
78
  type IsEqual<A, B> =
79
- (<G>() => G extends A ? 1 : 2) extends
80
- (<G>() => G extends B ? 1 : 2)
79
+ (<G>() => G extends A & G | G ? 1 : 2) extends
80
+ (<G>() => G extends B & G | G ? 1 : 2)
81
81
  ? true
82
82
  : false;
83
83
 
@@ -166,6 +166,72 @@ fn(someInterface as Simplify<SomeInterface>); // Good: transform an `interface`
166
166
  */
167
167
  type Simplify<T> = {[KeyType in keyof T]: T[KeyType]} & {};
168
168
 
169
+ /**
170
+ Returns a boolean for whether the given type is `never`.
171
+
172
+ @link https://github.com/microsoft/TypeScript/issues/31751#issuecomment-498526919
173
+ @link https://stackoverflow.com/a/53984913/10292952
174
+ @link https://www.zhenghao.io/posts/ts-never
175
+
176
+ Useful in type utilities, such as checking if something does not occur.
177
+
178
+ @example
179
+ ```
180
+ import type {IsNever, And} from 'type-fest';
181
+
182
+ // https://github.com/andnp/SimplyTyped/blob/master/src/types/strings.ts
183
+ type AreStringsEqual<A extends string, B extends string> =
184
+ And<
185
+ IsNever<Exclude<A, B>> extends true ? true : false,
186
+ IsNever<Exclude<B, A>> extends true ? true : false
187
+ >;
188
+
189
+ type EndIfEqual<I extends string, O extends string> =
190
+ AreStringsEqual<I, O> extends true
191
+ ? never
192
+ : void;
193
+
194
+ function endIfEqual<I extends string, O extends string>(input: I, output: O): EndIfEqual<I, O> {
195
+ if (input === output) {
196
+ process.exit(0);
197
+ }
198
+ }
199
+
200
+ endIfEqual('abc', 'abc');
201
+ //=> never
202
+
203
+ endIfEqual('abc', '123');
204
+ //=> void
205
+ ```
206
+
207
+ @category Type Guard
208
+ @category Utilities
209
+ */
210
+ type IsNever<T> = [T] extends [never] ? true : false;
211
+
212
+ /**
213
+ An if-else-like type that resolves depending on whether the given type is `never`.
214
+
215
+ @see {@link IsNever}
216
+
217
+ @example
218
+ ```
219
+ import type {IfNever} from 'type-fest';
220
+
221
+ type ShouldBeTrue = IfNever<never>;
222
+ //=> true
223
+
224
+ type ShouldBeBar = IfNever<'not never', 'foo', 'bar'>;
225
+ //=> 'bar'
226
+ ```
227
+
228
+ @category Type Guard
229
+ @category Utilities
230
+ */
231
+ type IfNever<T, TypeIfNever = true, TypeIfNotNever = false> = (
232
+ IsNever<T> extends true ? TypeIfNever : TypeIfNotNever
233
+ );
234
+
169
235
  /**
170
236
  Returns the static, fixed-length portion of the given array, excluding variable-length parts.
171
237
 
@@ -227,7 +293,7 @@ T extends readonly [...infer U] ?
227
293
  /**
228
294
  Returns whether the given array `T` is readonly.
229
295
  */
230
- type IsArrayReadonly<T extends UnknownArray> = T extends unknown[] ? false : true;
296
+ type IsArrayReadonly<T extends UnknownArray> = IfNever<T, false, T extends unknown[] ? false : true>;
231
297
 
232
298
  type StringDigit = '0' | '1' | '2' | '3' | '4' | '5' | '6' | '7' | '8' | '9';
233
299
 
@@ -324,49 +390,6 @@ type ShouldBeTrue = IsNegative<-1>;
324
390
  */
325
391
  type IsNegative<T extends Numeric> = T extends Negative<T> ? true : false;
326
392
 
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
393
  /**
371
394
  Returns a boolean for whether two given types are both true.
372
395
 
package/dist/index.d.ts CHANGED
@@ -76,8 +76,8 @@ type Includes<Value extends readonly any[], Item> =
76
76
  @category Utilities
77
77
  */
78
78
  type IsEqual<A, B> =
79
- (<G>() => G extends A ? 1 : 2) extends
80
- (<G>() => G extends B ? 1 : 2)
79
+ (<G>() => G extends A & G | G ? 1 : 2) extends
80
+ (<G>() => G extends B & G | G ? 1 : 2)
81
81
  ? true
82
82
  : false;
83
83
 
@@ -166,6 +166,72 @@ fn(someInterface as Simplify<SomeInterface>); // Good: transform an `interface`
166
166
  */
167
167
  type Simplify<T> = {[KeyType in keyof T]: T[KeyType]} & {};
168
168
 
169
+ /**
170
+ Returns a boolean for whether the given type is `never`.
171
+
172
+ @link https://github.com/microsoft/TypeScript/issues/31751#issuecomment-498526919
173
+ @link https://stackoverflow.com/a/53984913/10292952
174
+ @link https://www.zhenghao.io/posts/ts-never
175
+
176
+ Useful in type utilities, such as checking if something does not occur.
177
+
178
+ @example
179
+ ```
180
+ import type {IsNever, And} from 'type-fest';
181
+
182
+ // https://github.com/andnp/SimplyTyped/blob/master/src/types/strings.ts
183
+ type AreStringsEqual<A extends string, B extends string> =
184
+ And<
185
+ IsNever<Exclude<A, B>> extends true ? true : false,
186
+ IsNever<Exclude<B, A>> extends true ? true : false
187
+ >;
188
+
189
+ type EndIfEqual<I extends string, O extends string> =
190
+ AreStringsEqual<I, O> extends true
191
+ ? never
192
+ : void;
193
+
194
+ function endIfEqual<I extends string, O extends string>(input: I, output: O): EndIfEqual<I, O> {
195
+ if (input === output) {
196
+ process.exit(0);
197
+ }
198
+ }
199
+
200
+ endIfEqual('abc', 'abc');
201
+ //=> never
202
+
203
+ endIfEqual('abc', '123');
204
+ //=> void
205
+ ```
206
+
207
+ @category Type Guard
208
+ @category Utilities
209
+ */
210
+ type IsNever<T> = [T] extends [never] ? true : false;
211
+
212
+ /**
213
+ An if-else-like type that resolves depending on whether the given type is `never`.
214
+
215
+ @see {@link IsNever}
216
+
217
+ @example
218
+ ```
219
+ import type {IfNever} from 'type-fest';
220
+
221
+ type ShouldBeTrue = IfNever<never>;
222
+ //=> true
223
+
224
+ type ShouldBeBar = IfNever<'not never', 'foo', 'bar'>;
225
+ //=> 'bar'
226
+ ```
227
+
228
+ @category Type Guard
229
+ @category Utilities
230
+ */
231
+ type IfNever<T, TypeIfNever = true, TypeIfNotNever = false> = (
232
+ IsNever<T> extends true ? TypeIfNever : TypeIfNotNever
233
+ );
234
+
169
235
  /**
170
236
  Returns the static, fixed-length portion of the given array, excluding variable-length parts.
171
237
 
@@ -227,7 +293,7 @@ T extends readonly [...infer U] ?
227
293
  /**
228
294
  Returns whether the given array `T` is readonly.
229
295
  */
230
- type IsArrayReadonly<T extends UnknownArray> = T extends unknown[] ? false : true;
296
+ type IsArrayReadonly<T extends UnknownArray> = IfNever<T, false, T extends unknown[] ? false : true>;
231
297
 
232
298
  type StringDigit = '0' | '1' | '2' | '3' | '4' | '5' | '6' | '7' | '8' | '9';
233
299
 
@@ -324,49 +390,6 @@ type ShouldBeTrue = IsNegative<-1>;
324
390
  */
325
391
  type IsNegative<T extends Numeric> = T extends Negative<T> ? true : false;
326
392
 
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
393
  /**
371
394
  Returns a boolean for whether two given types are both true.
372
395