type-fest 4.9.0 → 4.10.0

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/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "type-fest",
3
- "version": "4.9.0",
3
+ "version": "4.10.0",
4
4
  "description": "A collection of essential TypeScript types",
5
5
  "license": "(MIT OR CC0-1.0)",
6
6
  "repository": "sindresorhus/type-fest",
@@ -1,4 +1,5 @@
1
1
  import type {DelimiterCase} from './delimiter-case';
2
+ import type {NonRecursiveType} from './internal';
2
3
  import type {UnknownArray} from './unknown-array';
3
4
 
4
5
  /**
@@ -48,7 +49,7 @@ const result: DelimiterCasedPropertiesDeep<UserWithFriends, '-'> = {
48
49
  export type DelimiterCasedPropertiesDeep<
49
50
  Value,
50
51
  Delimiter extends string,
51
- > = Value extends Function | Date | RegExp
52
+ > = Value extends NonRecursiveType
52
53
  ? Value
53
54
  : Value extends UnknownArray
54
55
  ? DelimiterCasedPropertiesArrayDeep<Value, Delimiter>
package/source/get.d.ts CHANGED
@@ -17,7 +17,7 @@ type GetOptions = {
17
17
  Like the `Get` type but receives an array of strings as a path parameter.
18
18
  */
19
19
  type GetWithPath<BaseType, Keys extends readonly string[], Options extends GetOptions = {}> =
20
- Keys extends []
20
+ Keys extends readonly []
21
21
  ? BaseType
22
22
  : Keys extends readonly [infer Head, ...infer Tail]
23
23
  ? GetWithPath<
@@ -125,7 +125,7 @@ type PropertyOf<BaseType, Key extends string, Options extends GetOptions = {}> =
125
125
  ? undefined
126
126
  : Key extends keyof BaseType
127
127
  ? StrictPropertyOf<BaseType, Key, Options>
128
- : BaseType extends [] | [unknown, ...unknown[]]
128
+ : BaseType extends readonly [] | readonly [unknown, ...unknown[]]
129
129
  ? unknown // It's a tuple, but `Key` did not extend `keyof BaseType`. So the index is out of bounds.
130
130
  : BaseType extends {
131
131
  [n: number]: infer Item;
@@ -436,3 +436,38 @@ type InternalUnionMax<N extends number, T extends UnknownArray = []> =
436
436
  : T['length'] extends N
437
437
  ? InternalUnionMax<Exclude<N, T['length']>, T>
438
438
  : InternalUnionMax<N, [...T, unknown]>;
439
+
440
+ /**
441
+ Returns a boolean for whether the given type is a union type.
442
+
443
+ @example
444
+ ```
445
+ type A = IsUnion<string | number>;
446
+ //=> true
447
+
448
+ type B = IsUnion<string>;
449
+ //=> false
450
+ ```
451
+ */
452
+ export type IsUnion<T> = InternalIsUnion<T>;
453
+
454
+ /**
455
+ The actual implementation of `IsUnion`.
456
+ */
457
+ type InternalIsUnion<T, U = T> =
458
+ (
459
+ // @link https://ghaiklor.github.io/type-challenges-solutions/en/medium-isunion.html
460
+ IsNever<T> extends true
461
+ ? false
462
+ : T extends any
463
+ ? [U] extends [T]
464
+ ? false
465
+ : true
466
+ : never
467
+ ) extends infer Result
468
+ // In some cases `Result` will return `false | true` which is `boolean`,
469
+ // that means `T` has at least two types and it's a union type,
470
+ // so we will return `true` instead of `boolean`.
471
+ ? boolean extends Result ? true
472
+ : Result
473
+ : never; // Should never happen
package/source/merge.d.ts CHANGED
@@ -1,6 +1,6 @@
1
1
  import type {OmitIndexSignature} from './omit-index-signature';
2
2
  import type {PickIndexSignature} from './pick-index-signature';
3
- import type {EnforceOptional} from './enforce-optional';
3
+ import type {Simplify} from './simplify';
4
4
 
5
5
  // Merges two objects without worrying about index signatures.
6
6
  type SimpleMerge<Destination, Source> = {
@@ -41,6 +41,8 @@ export type FooBar = Merge<Foo, Bar>;
41
41
 
42
42
  @category Object
43
43
  */
44
- export type Merge<Destination, Source> = EnforceOptional<
44
+ export type Merge<Destination, Source> =
45
+ Simplify<
45
46
  SimpleMerge<PickIndexSignature<Destination>, PickIndexSignature<Source>>
46
- & SimpleMerge<OmitIndexSignature<Destination>, OmitIndexSignature<Source>>>;
47
+ & SimpleMerge<OmitIndexSignature<Destination>, OmitIndexSignature<Source>>
48
+ >;
@@ -1,4 +1,4 @@
1
- import type {NonRecursiveType, UnionMin, UnionMax, TupleLength, StaticPartOfArray, VariablePartOfArray} from './internal';
1
+ import type {NonRecursiveType, UnionMin, UnionMax, TupleLength, StaticPartOfArray, VariablePartOfArray, IsUnion} from './internal';
2
2
  import type {IsNever} from './is-never';
3
3
  import type {UnknownArray} from './unknown-array';
4
4
 
@@ -108,10 +108,13 @@ function displayPetInfo(petInfo: SharedUnionFieldsDeep<Cat | Dog>['info']) {
108
108
  @category Union
109
109
  */
110
110
  export type SharedUnionFieldsDeep<Union, Options extends SharedUnionFieldsDeepOptions = {recurseIntoArrays: false}> =
111
+ // If `Union` is not a union type, return `Union` directly.
112
+ IsUnion<Union> extends false
113
+ ? Union
111
114
  // `Union extends` will convert `Union`
112
115
  // to a [distributive conditionaltype](https://www.typescriptlang.org/docs/handbook/release-notes/typescript-2-8.html#distributive-conditional-types).
113
116
  // But this is not what we want, so we need to wrap `Union` with `[]` to prevent it.
114
- [Union] extends [NonRecursiveType | ReadonlyMap<unknown, unknown> | ReadonlySet<unknown>]
117
+ : [Union] extends [NonRecursiveType | ReadonlyMap<unknown, unknown> | ReadonlySet<unknown>]
115
118
  ? Union
116
119
  : [Union] extends [UnknownArray]
117
120
  ? Options['recurseIntoArrays'] extends true