@visulima/object 1.0.6 → 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 +26 -0
- package/LICENSE.md +122 -0
- package/README.md +8 -8
- package/dist/index.cjs +187 -1
- package/dist/index.d.cts +105 -97
- package/dist/index.d.mts +105 -97
- package/dist/index.d.ts +105 -97
- 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 +18 -18
- package/dist/packem_shared/getProperty-C5Q_YpVO.mjs +0 -1
- package/dist/packem_shared/getProperty-D34HTBAJ.cjs +0 -1
- package/dist/packem_shared/isPlainObject-BTLAczOE.cjs +0 -1
- package/dist/packem_shared/isPlainObject-CFPUbgRS.mjs +0 -1
- package/dist/packem_shared/omit-Cwc8rJUb.cjs +0 -1
- package/dist/packem_shared/omit-Df-0bpNu.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-CS1_JC9v.mjs +0 -1
- package/dist/packem_shared/pick-CkwC0jUm.cjs +0 -1
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,10 +293,14 @@ 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
|
|
|
300
|
+
// Can eventually be replaced with the built-in once this library supports
|
|
301
|
+
// TS5.4+ only. Tracked in https://github.com/sindresorhus/type-fest/issues/848
|
|
302
|
+
type NoInfer<T> = T extends infer U ? U : never;
|
|
303
|
+
|
|
234
304
|
/**
|
|
235
305
|
Returns a boolean for whether the given type is `any`.
|
|
236
306
|
|
|
@@ -259,7 +329,7 @@ const anyA = get(anyObject, 'a');
|
|
|
259
329
|
@category Type Guard
|
|
260
330
|
@category Utilities
|
|
261
331
|
*/
|
|
262
|
-
type IsAny<T> = 0 extends 1 & T ? true : false;
|
|
332
|
+
type IsAny<T> = 0 extends 1 & NoInfer<T> ? true : false;
|
|
263
333
|
|
|
264
334
|
type Numeric = number | bigint;
|
|
265
335
|
|
|
@@ -320,49 +390,6 @@ type ShouldBeTrue = IsNegative<-1>;
|
|
|
320
390
|
*/
|
|
321
391
|
type IsNegative<T extends Numeric> = T extends Negative<T> ? true : false;
|
|
322
392
|
|
|
323
|
-
/**
|
|
324
|
-
Returns a boolean for whether the given type is `never`.
|
|
325
|
-
|
|
326
|
-
@link https://github.com/microsoft/TypeScript/issues/31751#issuecomment-498526919
|
|
327
|
-
@link https://stackoverflow.com/a/53984913/10292952
|
|
328
|
-
@link https://www.zhenghao.io/posts/ts-never
|
|
329
|
-
|
|
330
|
-
Useful in type utilities, such as checking if something does not occur.
|
|
331
|
-
|
|
332
|
-
@example
|
|
333
|
-
```
|
|
334
|
-
import type {IsNever, And} from 'type-fest';
|
|
335
|
-
|
|
336
|
-
// https://github.com/andnp/SimplyTyped/blob/master/src/types/strings.ts
|
|
337
|
-
type AreStringsEqual<A extends string, B extends string> =
|
|
338
|
-
And<
|
|
339
|
-
IsNever<Exclude<A, B>> extends true ? true : false,
|
|
340
|
-
IsNever<Exclude<B, A>> extends true ? true : false
|
|
341
|
-
>;
|
|
342
|
-
|
|
343
|
-
type EndIfEqual<I extends string, O extends string> =
|
|
344
|
-
AreStringsEqual<I, O> extends true
|
|
345
|
-
? never
|
|
346
|
-
: void;
|
|
347
|
-
|
|
348
|
-
function endIfEqual<I extends string, O extends string>(input: I, output: O): EndIfEqual<I, O> {
|
|
349
|
-
if (input === output) {
|
|
350
|
-
process.exit(0);
|
|
351
|
-
}
|
|
352
|
-
}
|
|
353
|
-
|
|
354
|
-
endIfEqual('abc', 'abc');
|
|
355
|
-
//=> never
|
|
356
|
-
|
|
357
|
-
endIfEqual('abc', '123');
|
|
358
|
-
//=> void
|
|
359
|
-
```
|
|
360
|
-
|
|
361
|
-
@category Type Guard
|
|
362
|
-
@category Utilities
|
|
363
|
-
*/
|
|
364
|
-
type IsNever<T> = [T] extends [never] ? true : false;
|
|
365
|
-
|
|
366
393
|
/**
|
|
367
394
|
Returns a boolean for whether two given types are both true.
|
|
368
395
|
|
|
@@ -866,41 +893,6 @@ Matches non-recursive types.
|
|
|
866
893
|
*/
|
|
867
894
|
type NonRecursiveType = BuiltIns | Function | (new (...arguments_: any[]) => unknown);
|
|
868
895
|
|
|
869
|
-
/**
|
|
870
|
-
Returns a boolean for whether the given type is a union type.
|
|
871
|
-
|
|
872
|
-
@example
|
|
873
|
-
```
|
|
874
|
-
type A = IsUnion<string | number>;
|
|
875
|
-
//=> true
|
|
876
|
-
|
|
877
|
-
type B = IsUnion<string>;
|
|
878
|
-
//=> false
|
|
879
|
-
```
|
|
880
|
-
*/
|
|
881
|
-
type IsUnion<T> = InternalIsUnion<T>;
|
|
882
|
-
|
|
883
|
-
/**
|
|
884
|
-
The actual implementation of `IsUnion`.
|
|
885
|
-
*/
|
|
886
|
-
type InternalIsUnion<T, U = T> =
|
|
887
|
-
(
|
|
888
|
-
// @link https://ghaiklor.github.io/type-challenges-solutions/en/medium-isunion.html
|
|
889
|
-
IsNever<T> extends true
|
|
890
|
-
? false
|
|
891
|
-
: T extends any
|
|
892
|
-
? [U] extends [T]
|
|
893
|
-
? false
|
|
894
|
-
: true
|
|
895
|
-
: never
|
|
896
|
-
) extends infer Result
|
|
897
|
-
// In some cases `Result` will return `false | true` which is `boolean`,
|
|
898
|
-
// that means `T` has at least two types and it's a union type,
|
|
899
|
-
// so we will return `true` instead of `boolean`.
|
|
900
|
-
? boolean extends Result ? true
|
|
901
|
-
: Result
|
|
902
|
-
: never; // Should never happen
|
|
903
|
-
|
|
904
896
|
/**
|
|
905
897
|
Create an object type with the given key `<Key>` and value `<Value>`.
|
|
906
898
|
|
|
@@ -1725,13 +1717,13 @@ type Dog = {
|
|
|
1725
1717
|
function displayPetInfo(petInfo: (Cat | Dog)['info']) {
|
|
1726
1718
|
// typeof petInfo =>
|
|
1727
1719
|
// {
|
|
1728
|
-
//
|
|
1729
|
-
//
|
|
1730
|
-
//
|
|
1720
|
+
// name: string;
|
|
1721
|
+
// type: 'cat';
|
|
1722
|
+
// catType: string; // Needn't care about this field, because it's not a common pet info field.
|
|
1731
1723
|
// } | {
|
|
1732
|
-
//
|
|
1733
|
-
//
|
|
1734
|
-
//
|
|
1724
|
+
// name: string;
|
|
1725
|
+
// type: 'dog';
|
|
1726
|
+
// dogType: string; // Needn't care about this field, because it's not a common pet info field.
|
|
1735
1727
|
// }
|
|
1736
1728
|
|
|
1737
1729
|
// petInfo type is complex and have some needless fields
|
|
@@ -1743,8 +1735,8 @@ function displayPetInfo(petInfo: (Cat | Dog)['info']) {
|
|
|
1743
1735
|
function displayPetInfo(petInfo: SharedUnionFieldsDeep<Cat | Dog>['info']) {
|
|
1744
1736
|
// typeof petInfo =>
|
|
1745
1737
|
// {
|
|
1746
|
-
//
|
|
1747
|
-
//
|
|
1738
|
+
// name: string;
|
|
1739
|
+
// type: 'cat' | 'dog';
|
|
1748
1740
|
// }
|
|
1749
1741
|
|
|
1750
1742
|
// petInfo type is simple and clear
|
|
@@ -1754,17 +1746,16 @@ function displayPetInfo(petInfo: SharedUnionFieldsDeep<Cat | Dog>['info']) {
|
|
|
1754
1746
|
}
|
|
1755
1747
|
```
|
|
1756
1748
|
|
|
1749
|
+
@see SharedUnionFields
|
|
1750
|
+
|
|
1757
1751
|
@category Object
|
|
1758
1752
|
@category Union
|
|
1759
1753
|
*/
|
|
1760
1754
|
type SharedUnionFieldsDeep<Union, Options extends SharedUnionFieldsDeepOptions = {recurseIntoArrays: false}> =
|
|
1761
|
-
// If `Union` is not a union type, return `Union` directly.
|
|
1762
|
-
IsUnion<Union> extends false
|
|
1763
|
-
? Union
|
|
1764
1755
|
// `Union extends` will convert `Union`
|
|
1765
1756
|
// to a [distributive conditionaltype](https://www.typescriptlang.org/docs/handbook/release-notes/typescript-2-8.html#distributive-conditional-types).
|
|
1766
1757
|
// But this is not what we want, so we need to wrap `Union` with `[]` to prevent it.
|
|
1767
|
-
|
|
1758
|
+
[Union] extends [NonRecursiveType | ReadonlyMap<unknown, unknown> | ReadonlySet<unknown>]
|
|
1768
1759
|
? Union
|
|
1769
1760
|
: [Union] extends [UnknownArray]
|
|
1770
1761
|
? Options['recurseIntoArrays'] extends true
|
|
@@ -1778,13 +1769,18 @@ IsUnion<Union> extends false
|
|
|
1778
1769
|
Same as `SharedUnionFieldsDeep`, but accepts only `object`s and as inputs. Internal helper for `SharedUnionFieldsDeep`.
|
|
1779
1770
|
*/
|
|
1780
1771
|
type SharedObjectUnionFieldsDeep<Union, Options extends SharedUnionFieldsDeepOptions> =
|
|
1772
|
+
// `keyof Union` can extract the same key in union type, if there is no same key, return never.
|
|
1781
1773
|
keyof Union extends infer Keys
|
|
1782
1774
|
? IsNever<Keys> extends false
|
|
1783
1775
|
? {
|
|
1784
1776
|
[Key in keyof Union]:
|
|
1785
1777
|
Union[Key] extends NonRecursiveType
|
|
1786
1778
|
? Union[Key]
|
|
1787
|
-
|
|
1779
|
+
// Remove `undefined` from the union to support optional
|
|
1780
|
+
// fields, then recover `undefined` if union was already undefined.
|
|
1781
|
+
: SharedUnionFieldsDeep<Exclude<Union[Key], undefined>, Options> | (
|
|
1782
|
+
undefined extends Required<Union>[Key] ? undefined : never
|
|
1783
|
+
)
|
|
1788
1784
|
}
|
|
1789
1785
|
: {}
|
|
1790
1786
|
: Union;
|
|
@@ -2173,8 +2169,20 @@ type PropertyOf<BaseType, Key extends string, Options extends GetOptions = {}> =
|
|
|
2173
2169
|
? undefined
|
|
2174
2170
|
: Key extends keyof BaseType
|
|
2175
2171
|
? StrictPropertyOf<BaseType, Key, Options>
|
|
2176
|
-
|
|
2177
|
-
|
|
2172
|
+
// Handle arrays and tuples
|
|
2173
|
+
: BaseType extends readonly unknown[]
|
|
2174
|
+
? Key extends `${number}`
|
|
2175
|
+
// For arrays with unknown length (regular arrays)
|
|
2176
|
+
? number extends BaseType['length']
|
|
2177
|
+
? Strictify<BaseType[number], Options>
|
|
2178
|
+
// For tuples: check if the index is valid
|
|
2179
|
+
: Key extends keyof BaseType
|
|
2180
|
+
? Strictify<BaseType[Key & keyof BaseType], Options>
|
|
2181
|
+
// Out-of-bounds access for tuples
|
|
2182
|
+
: unknown
|
|
2183
|
+
// Non-numeric string key for arrays/tuples
|
|
2184
|
+
: unknown
|
|
2185
|
+
// Handle array-like objects
|
|
2178
2186
|
: BaseType extends {
|
|
2179
2187
|
[n: number]: infer Item;
|
|
2180
2188
|
length: number; // Note: This is needed to avoid being too lax with records types using number keys like `{0: string; 1: boolean}`.
|
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,10 +293,14 @@ 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
|
|
|
300
|
+
// Can eventually be replaced with the built-in once this library supports
|
|
301
|
+
// TS5.4+ only. Tracked in https://github.com/sindresorhus/type-fest/issues/848
|
|
302
|
+
type NoInfer<T> = T extends infer U ? U : never;
|
|
303
|
+
|
|
234
304
|
/**
|
|
235
305
|
Returns a boolean for whether the given type is `any`.
|
|
236
306
|
|
|
@@ -259,7 +329,7 @@ const anyA = get(anyObject, 'a');
|
|
|
259
329
|
@category Type Guard
|
|
260
330
|
@category Utilities
|
|
261
331
|
*/
|
|
262
|
-
type IsAny<T> = 0 extends 1 & T ? true : false;
|
|
332
|
+
type IsAny<T> = 0 extends 1 & NoInfer<T> ? true : false;
|
|
263
333
|
|
|
264
334
|
type Numeric = number | bigint;
|
|
265
335
|
|
|
@@ -320,49 +390,6 @@ type ShouldBeTrue = IsNegative<-1>;
|
|
|
320
390
|
*/
|
|
321
391
|
type IsNegative<T extends Numeric> = T extends Negative<T> ? true : false;
|
|
322
392
|
|
|
323
|
-
/**
|
|
324
|
-
Returns a boolean for whether the given type is `never`.
|
|
325
|
-
|
|
326
|
-
@link https://github.com/microsoft/TypeScript/issues/31751#issuecomment-498526919
|
|
327
|
-
@link https://stackoverflow.com/a/53984913/10292952
|
|
328
|
-
@link https://www.zhenghao.io/posts/ts-never
|
|
329
|
-
|
|
330
|
-
Useful in type utilities, such as checking if something does not occur.
|
|
331
|
-
|
|
332
|
-
@example
|
|
333
|
-
```
|
|
334
|
-
import type {IsNever, And} from 'type-fest';
|
|
335
|
-
|
|
336
|
-
// https://github.com/andnp/SimplyTyped/blob/master/src/types/strings.ts
|
|
337
|
-
type AreStringsEqual<A extends string, B extends string> =
|
|
338
|
-
And<
|
|
339
|
-
IsNever<Exclude<A, B>> extends true ? true : false,
|
|
340
|
-
IsNever<Exclude<B, A>> extends true ? true : false
|
|
341
|
-
>;
|
|
342
|
-
|
|
343
|
-
type EndIfEqual<I extends string, O extends string> =
|
|
344
|
-
AreStringsEqual<I, O> extends true
|
|
345
|
-
? never
|
|
346
|
-
: void;
|
|
347
|
-
|
|
348
|
-
function endIfEqual<I extends string, O extends string>(input: I, output: O): EndIfEqual<I, O> {
|
|
349
|
-
if (input === output) {
|
|
350
|
-
process.exit(0);
|
|
351
|
-
}
|
|
352
|
-
}
|
|
353
|
-
|
|
354
|
-
endIfEqual('abc', 'abc');
|
|
355
|
-
//=> never
|
|
356
|
-
|
|
357
|
-
endIfEqual('abc', '123');
|
|
358
|
-
//=> void
|
|
359
|
-
```
|
|
360
|
-
|
|
361
|
-
@category Type Guard
|
|
362
|
-
@category Utilities
|
|
363
|
-
*/
|
|
364
|
-
type IsNever<T> = [T] extends [never] ? true : false;
|
|
365
|
-
|
|
366
393
|
/**
|
|
367
394
|
Returns a boolean for whether two given types are both true.
|
|
368
395
|
|
|
@@ -866,41 +893,6 @@ Matches non-recursive types.
|
|
|
866
893
|
*/
|
|
867
894
|
type NonRecursiveType = BuiltIns | Function | (new (...arguments_: any[]) => unknown);
|
|
868
895
|
|
|
869
|
-
/**
|
|
870
|
-
Returns a boolean for whether the given type is a union type.
|
|
871
|
-
|
|
872
|
-
@example
|
|
873
|
-
```
|
|
874
|
-
type A = IsUnion<string | number>;
|
|
875
|
-
//=> true
|
|
876
|
-
|
|
877
|
-
type B = IsUnion<string>;
|
|
878
|
-
//=> false
|
|
879
|
-
```
|
|
880
|
-
*/
|
|
881
|
-
type IsUnion<T> = InternalIsUnion<T>;
|
|
882
|
-
|
|
883
|
-
/**
|
|
884
|
-
The actual implementation of `IsUnion`.
|
|
885
|
-
*/
|
|
886
|
-
type InternalIsUnion<T, U = T> =
|
|
887
|
-
(
|
|
888
|
-
// @link https://ghaiklor.github.io/type-challenges-solutions/en/medium-isunion.html
|
|
889
|
-
IsNever<T> extends true
|
|
890
|
-
? false
|
|
891
|
-
: T extends any
|
|
892
|
-
? [U] extends [T]
|
|
893
|
-
? false
|
|
894
|
-
: true
|
|
895
|
-
: never
|
|
896
|
-
) extends infer Result
|
|
897
|
-
// In some cases `Result` will return `false | true` which is `boolean`,
|
|
898
|
-
// that means `T` has at least two types and it's a union type,
|
|
899
|
-
// so we will return `true` instead of `boolean`.
|
|
900
|
-
? boolean extends Result ? true
|
|
901
|
-
: Result
|
|
902
|
-
: never; // Should never happen
|
|
903
|
-
|
|
904
896
|
/**
|
|
905
897
|
Create an object type with the given key `<Key>` and value `<Value>`.
|
|
906
898
|
|
|
@@ -1725,13 +1717,13 @@ type Dog = {
|
|
|
1725
1717
|
function displayPetInfo(petInfo: (Cat | Dog)['info']) {
|
|
1726
1718
|
// typeof petInfo =>
|
|
1727
1719
|
// {
|
|
1728
|
-
//
|
|
1729
|
-
//
|
|
1730
|
-
//
|
|
1720
|
+
// name: string;
|
|
1721
|
+
// type: 'cat';
|
|
1722
|
+
// catType: string; // Needn't care about this field, because it's not a common pet info field.
|
|
1731
1723
|
// } | {
|
|
1732
|
-
//
|
|
1733
|
-
//
|
|
1734
|
-
//
|
|
1724
|
+
// name: string;
|
|
1725
|
+
// type: 'dog';
|
|
1726
|
+
// dogType: string; // Needn't care about this field, because it's not a common pet info field.
|
|
1735
1727
|
// }
|
|
1736
1728
|
|
|
1737
1729
|
// petInfo type is complex and have some needless fields
|
|
@@ -1743,8 +1735,8 @@ function displayPetInfo(petInfo: (Cat | Dog)['info']) {
|
|
|
1743
1735
|
function displayPetInfo(petInfo: SharedUnionFieldsDeep<Cat | Dog>['info']) {
|
|
1744
1736
|
// typeof petInfo =>
|
|
1745
1737
|
// {
|
|
1746
|
-
//
|
|
1747
|
-
//
|
|
1738
|
+
// name: string;
|
|
1739
|
+
// type: 'cat' | 'dog';
|
|
1748
1740
|
// }
|
|
1749
1741
|
|
|
1750
1742
|
// petInfo type is simple and clear
|
|
@@ -1754,17 +1746,16 @@ function displayPetInfo(petInfo: SharedUnionFieldsDeep<Cat | Dog>['info']) {
|
|
|
1754
1746
|
}
|
|
1755
1747
|
```
|
|
1756
1748
|
|
|
1749
|
+
@see SharedUnionFields
|
|
1750
|
+
|
|
1757
1751
|
@category Object
|
|
1758
1752
|
@category Union
|
|
1759
1753
|
*/
|
|
1760
1754
|
type SharedUnionFieldsDeep<Union, Options extends SharedUnionFieldsDeepOptions = {recurseIntoArrays: false}> =
|
|
1761
|
-
// If `Union` is not a union type, return `Union` directly.
|
|
1762
|
-
IsUnion<Union> extends false
|
|
1763
|
-
? Union
|
|
1764
1755
|
// `Union extends` will convert `Union`
|
|
1765
1756
|
// to a [distributive conditionaltype](https://www.typescriptlang.org/docs/handbook/release-notes/typescript-2-8.html#distributive-conditional-types).
|
|
1766
1757
|
// But this is not what we want, so we need to wrap `Union` with `[]` to prevent it.
|
|
1767
|
-
|
|
1758
|
+
[Union] extends [NonRecursiveType | ReadonlyMap<unknown, unknown> | ReadonlySet<unknown>]
|
|
1768
1759
|
? Union
|
|
1769
1760
|
: [Union] extends [UnknownArray]
|
|
1770
1761
|
? Options['recurseIntoArrays'] extends true
|
|
@@ -1778,13 +1769,18 @@ IsUnion<Union> extends false
|
|
|
1778
1769
|
Same as `SharedUnionFieldsDeep`, but accepts only `object`s and as inputs. Internal helper for `SharedUnionFieldsDeep`.
|
|
1779
1770
|
*/
|
|
1780
1771
|
type SharedObjectUnionFieldsDeep<Union, Options extends SharedUnionFieldsDeepOptions> =
|
|
1772
|
+
// `keyof Union` can extract the same key in union type, if there is no same key, return never.
|
|
1781
1773
|
keyof Union extends infer Keys
|
|
1782
1774
|
? IsNever<Keys> extends false
|
|
1783
1775
|
? {
|
|
1784
1776
|
[Key in keyof Union]:
|
|
1785
1777
|
Union[Key] extends NonRecursiveType
|
|
1786
1778
|
? Union[Key]
|
|
1787
|
-
|
|
1779
|
+
// Remove `undefined` from the union to support optional
|
|
1780
|
+
// fields, then recover `undefined` if union was already undefined.
|
|
1781
|
+
: SharedUnionFieldsDeep<Exclude<Union[Key], undefined>, Options> | (
|
|
1782
|
+
undefined extends Required<Union>[Key] ? undefined : never
|
|
1783
|
+
)
|
|
1788
1784
|
}
|
|
1789
1785
|
: {}
|
|
1790
1786
|
: Union;
|
|
@@ -2173,8 +2169,20 @@ type PropertyOf<BaseType, Key extends string, Options extends GetOptions = {}> =
|
|
|
2173
2169
|
? undefined
|
|
2174
2170
|
: Key extends keyof BaseType
|
|
2175
2171
|
? StrictPropertyOf<BaseType, Key, Options>
|
|
2176
|
-
|
|
2177
|
-
|
|
2172
|
+
// Handle arrays and tuples
|
|
2173
|
+
: BaseType extends readonly unknown[]
|
|
2174
|
+
? Key extends `${number}`
|
|
2175
|
+
// For arrays with unknown length (regular arrays)
|
|
2176
|
+
? number extends BaseType['length']
|
|
2177
|
+
? Strictify<BaseType[number], Options>
|
|
2178
|
+
// For tuples: check if the index is valid
|
|
2179
|
+
: Key extends keyof BaseType
|
|
2180
|
+
? Strictify<BaseType[Key & keyof BaseType], Options>
|
|
2181
|
+
// Out-of-bounds access for tuples
|
|
2182
|
+
: unknown
|
|
2183
|
+
// Non-numeric string key for arrays/tuples
|
|
2184
|
+
: unknown
|
|
2185
|
+
// Handle array-like objects
|
|
2178
2186
|
: BaseType extends {
|
|
2179
2187
|
[n: number]: infer Item;
|
|
2180
2188
|
length: number; // Note: This is needed to avoid being too lax with records types using number keys like `{0: string; 1: boolean}`.
|