type-fest 5.4.4 → 5.6.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.
Files changed (100) hide show
  1. package/index.d.ts +10 -0
  2. package/package.json +6 -4
  3. package/readme.md +83 -58
  4. package/source/absolute.d.ts +52 -0
  5. package/source/all-extend.d.ts +5 -6
  6. package/source/all-union-fields.d.ts +18 -18
  7. package/source/and-all.d.ts +76 -0
  8. package/source/and.d.ts +4 -3
  9. package/source/array-length.d.ts +36 -0
  10. package/source/array-splice.d.ts +26 -26
  11. package/source/camel-case.d.ts +38 -5
  12. package/source/camel-cased-properties-deep.d.ts +11 -4
  13. package/source/camel-cased-properties.d.ts +5 -1
  14. package/source/conditional-pick-deep.d.ts +5 -3
  15. package/source/conditional-pick.d.ts +6 -4
  16. package/source/delimiter-case.d.ts +1 -0
  17. package/source/delimiter-cased-properties-deep.d.ts +8 -1
  18. package/source/delimiter-cased-properties.d.ts +5 -1
  19. package/source/empty-object.d.ts +1 -1
  20. package/source/entries.d.ts +1 -1
  21. package/source/entry.d.ts +1 -1
  22. package/source/exclude-exactly.d.ts +57 -0
  23. package/source/get.d.ts +1 -1
  24. package/source/greater-than-or-equal.d.ts +34 -1
  25. package/source/greater-than.d.ts +37 -3
  26. package/source/has-optional-keys.d.ts +1 -1
  27. package/source/has-readonly-keys.d.ts +1 -1
  28. package/source/has-required-keys.d.ts +1 -1
  29. package/source/has-writable-keys.d.ts +1 -1
  30. package/source/int-closed-range.d.ts +1 -3
  31. package/source/int-range.d.ts +3 -5
  32. package/source/internal/array.d.ts +7 -14
  33. package/source/internal/keys.d.ts +9 -9
  34. package/source/internal/numeric.d.ts +13 -23
  35. package/source/internal/tuple.d.ts +3 -3
  36. package/source/internal/type.d.ts +1 -0
  37. package/source/is-equal.d.ts +0 -1
  38. package/source/is-integer.d.ts +8 -8
  39. package/source/is-literal.d.ts +5 -5
  40. package/source/is-union.d.ts +12 -12
  41. package/source/iterable-element.d.ts +5 -5
  42. package/source/jsonify.d.ts +4 -4
  43. package/source/kebab-case.d.ts +1 -0
  44. package/source/kebab-cased-properties-deep.d.ts +7 -0
  45. package/source/kebab-cased-properties.d.ts +5 -1
  46. package/source/keys-of-union.d.ts +2 -2
  47. package/source/less-than-or-equal.d.ts +40 -4
  48. package/source/less-than.d.ts +35 -3
  49. package/source/literal-to-primitive.d.ts +1 -1
  50. package/source/literal-union.d.ts +1 -1
  51. package/source/merge-exclusive.d.ts +3 -3
  52. package/source/merge.d.ts +25 -0
  53. package/source/multidimensional-array.d.ts +1 -1
  54. package/source/multidimensional-readonly-array.d.ts +1 -1
  55. package/source/non-nullable-deep.d.ts +102 -0
  56. package/source/numeric.d.ts +3 -3
  57. package/source/omit-deep.d.ts +22 -23
  58. package/source/optional.d.ts +31 -0
  59. package/source/or-all.d.ts +73 -0
  60. package/source/or.d.ts +4 -11
  61. package/source/package-json.d.ts +7 -7
  62. package/source/partial-deep.d.ts +3 -1
  63. package/source/pascal-case.d.ts +1 -0
  64. package/source/pascal-cased-properties-deep.d.ts +7 -0
  65. package/source/pascal-cased-properties.d.ts +5 -1
  66. package/source/pick-deep.d.ts +8 -21
  67. package/source/readonly-deep.d.ts +5 -3
  68. package/source/remove-prefix.d.ts +15 -15
  69. package/source/replace.d.ts +2 -2
  70. package/source/require-all-or-none.d.ts +1 -1
  71. package/source/require-at-least-one.d.ts +5 -7
  72. package/source/require-exactly-one.d.ts +3 -3
  73. package/source/require-one-or-none.d.ts +1 -1
  74. package/source/required-deep.d.ts +3 -1
  75. package/source/screaming-snake-case.d.ts +1 -0
  76. package/source/set-non-nullable-deep.d.ts +6 -3
  77. package/source/set-non-nullable.d.ts +4 -11
  78. package/source/set-optional.d.ts +6 -10
  79. package/source/set-parameter-type.d.ts +2 -2
  80. package/source/set-readonly.d.ts +4 -8
  81. package/source/set-required-deep.d.ts +1 -1
  82. package/source/set-required.d.ts +4 -8
  83. package/source/shared-union-fields-deep.d.ts +1 -1
  84. package/source/shared-union-fields.d.ts +9 -9
  85. package/source/snake-case.d.ts +1 -0
  86. package/source/snake-cased-properties-deep.d.ts +7 -0
  87. package/source/snake-cased-properties.d.ts +5 -1
  88. package/source/some-extend.d.ts +113 -0
  89. package/source/spread.d.ts +1 -5
  90. package/source/subtract.d.ts +4 -3
  91. package/source/sum.d.ts +5 -4
  92. package/source/tagged.d.ts +5 -7
  93. package/source/tsconfig-json.d.ts +39 -7
  94. package/source/union-length.d.ts +27 -0
  95. package/source/union-member.d.ts +65 -0
  96. package/source/union-to-intersection.d.ts +1 -1
  97. package/source/union-to-tuple.d.ts +10 -19
  98. package/source/words.d.ts +30 -4
  99. package/source/writable.d.ts +15 -19
  100. package/source/xor.d.ts +1 -1
@@ -4,13 +4,6 @@ import type {OptionalKeysOf} from '../optional-keys-of.d.ts';
4
4
  import type {UnknownArray} from '../unknown-array.d.ts';
5
5
  import type {IsExactOptionalPropertyTypesEnabled, IfNotAnyOrNever} from './type.d.ts';
6
6
 
7
- /**
8
- Infer the length of the given array `<T>`.
9
-
10
- @link https://itnext.io/implementing-arithmetic-within-typescripts-type-system-a1ef140a6f6f
11
- */
12
- type ArrayLength<T extends readonly unknown[]> = T extends {readonly length: infer L} ? L : never;
13
-
14
7
  /**
15
8
  Matches any unknown array or tuple.
16
9
  */
@@ -36,8 +29,8 @@ type B = StaticPartOfArray<A>;
36
29
  */
37
30
  export type StaticPartOfArray<T extends UnknownArray, Result extends UnknownArray = []> =
38
31
  T extends unknown
39
- ? number extends T['length'] ?
40
- T extends readonly [infer U, ...infer V]
32
+ ? number extends T['length']
33
+ ? T extends readonly [infer U, ...infer V]
41
34
  ? StaticPartOfArray<V, [...Result, U]>
42
35
  : Result
43
36
  : T
@@ -76,11 +69,11 @@ type NormalResult = SetArrayAccess<ReadonlyStringArray, false>;
76
69
  ```
77
70
  */
78
71
  export type SetArrayAccess<T extends UnknownArray, IsReadonly extends boolean> =
79
- T extends readonly [...infer U] ?
80
- IsReadonly extends true
81
- ? readonly [...U]
82
- : [...U]
83
- : T;
72
+ T extends readonly [...infer U]
73
+ ? IsReadonly extends true
74
+ ? readonly [...U]
75
+ : [...U]
76
+ : T;
84
77
 
85
78
  /**
86
79
  Returns whether the given array `T` is readonly.
@@ -87,14 +87,14 @@ type Key4 = ExactKey<Object, 1>;
87
87
  @category Object
88
88
  */
89
89
  export type ExactKey<T extends object, Key extends PropertyKey> =
90
- Key extends keyof T
91
- ? Key
92
- : ToString<Key> extends keyof T
93
- ? ToString<Key>
94
- : Key extends `${infer NumberKey extends number}`
95
- ? NumberKey extends keyof T
96
- ? NumberKey
97
- : never
98
- : never;
90
+ Key extends keyof T
91
+ ? Key
92
+ : ToString<Key> extends keyof T
93
+ ? ToString<Key>
94
+ : Key extends `${infer NumberKey extends number}`
95
+ ? NumberKey extends keyof T
96
+ ? NumberKey
97
+ : never
98
+ : never;
99
99
 
100
100
  export {};
@@ -1,26 +1,8 @@
1
1
  import type {IsNever} from '../is-never.d.ts';
2
2
  import type {Finite, NegativeInfinity, PositiveInfinity} from '../numeric.d.ts';
3
3
  import type {UnknownArray} from '../unknown-array.d.ts';
4
- import type {StringToNumber} from './string.d.ts';
5
4
  import type {IfNotAnyOrNever, IsAnyOrNever} from './type.d.ts';
6
5
 
7
- /**
8
- Returns the absolute value of a given value.
9
-
10
- @example
11
- ```
12
- type A = NumberAbsolute<-1>;
13
- //=> 1
14
-
15
- type B = NumberAbsolute<1>;
16
- //=> 1
17
-
18
- type C = NumberAbsolute<NegativeInfinity>;
19
- //=> PositiveInfinity
20
- ```
21
- */
22
- export type NumberAbsolute<N extends number> = `${N}` extends `-${infer StringPositiveN}` ? StringToNumber<StringPositiveN> : N;
23
-
24
6
  /**
25
7
  Check whether the given type is a number or a number string.
26
8
 
@@ -142,10 +124,18 @@ type D = ReverseSign<PositiveInfinity>;
142
124
  */
143
125
  export type ReverseSign<N extends number> =
144
126
  // Handle edge cases
145
- N extends 0 ? 0 : N extends PositiveInfinity ? NegativeInfinity : N extends NegativeInfinity ? PositiveInfinity :
146
- // Handle negative numbers
147
- `${N}` extends `-${infer P extends number}` ? P
148
- // Handle positive numbers
149
- : `-${N}` extends `${infer R extends number}` ? R : never;
127
+ N extends 0
128
+ ? 0
129
+ : N extends PositiveInfinity
130
+ ? NegativeInfinity
131
+ : N extends NegativeInfinity
132
+ ? PositiveInfinity
133
+ // Handle negative numbers
134
+ : `${N}` extends `-${infer P extends number}`
135
+ ? P
136
+ // Handle positive numbers
137
+ : `-${N}` extends `${infer R extends number}`
138
+ ? R
139
+ : never;
150
140
 
151
141
  export {};
@@ -23,7 +23,7 @@ type Union = TupleLength<[] | [1, 2, 3] | number[]>;
23
23
  */
24
24
  export type TupleLength<T extends UnknownArray> =
25
25
  // `extends unknown` is used to convert `T` (if `T` is a union type) to
26
- // a [distributive conditionaltype](https://www.typescriptlang.org/docs/handbook/release-notes/typescript-2-8.html#distributive-conditional-types))
26
+ // a [distributive conditional type](https://www.typescriptlang.org/docs/handbook/release-notes/typescript-2-8.html#distributive-conditional-types))
27
27
  T extends unknown
28
28
  ? number extends T['length']
29
29
  ? never // Return never if the given type is an non-flexed-length array like `Array<string>`
@@ -46,8 +46,8 @@ type B = TupleMax<[1, 2, 5, 3, 99, -1]>;
46
46
  ```
47
47
  */
48
48
  export type TupleMax<A extends number[], Result extends number = NegativeInfinity> = number extends A[number]
49
- ? never :
50
- A extends [infer F extends number, ...infer R extends number[]]
49
+ ? never
50
+ : A extends [infer F extends number, ...infer R extends number[]]
51
51
  ? GreaterThan<F, Result> extends true
52
52
  ? TupleMax<R, F>
53
53
  : TupleMax<R, Result>
@@ -3,6 +3,7 @@ import type {IsAny} from '../is-any.d.ts';
3
3
  import type {IsNever} from '../is-never.d.ts';
4
4
  import type {Primitive} from '../primitive.d.ts';
5
5
  import type {UnknownArray} from '../unknown-array.d.ts';
6
+ import type {UnionToIntersection} from '../union-to-intersection.d.ts';
6
7
 
7
8
  /**
8
9
  Matches any primitive, `void`, `Date`, or `RegExp` value.
@@ -1,4 +1,3 @@
1
- import type {IsNever} from './is-never.d.ts';
2
1
  /**
3
2
  Returns a boolean for whether the two given types are equal.
4
3
 
@@ -47,14 +47,14 @@ type J = IsInteger<1e-7>;
47
47
  @category Numeric
48
48
  */
49
49
  export type IsInteger<T> =
50
- T extends bigint
51
- ? true
52
- : T extends number
53
- ? number extends T
54
- ? false
55
- : T extends PositiveInfinity | NegativeInfinity
50
+ T extends bigint
51
+ ? true
52
+ : T extends number
53
+ ? number extends T
56
54
  ? false
57
- : Not<IsFloat<T>>
58
- : false;
55
+ : T extends PositiveInfinity | NegativeInfinity
56
+ ? false
57
+ : Not<IsFloat<T>>
58
+ : false;
59
59
 
60
60
  export {};
@@ -121,11 +121,11 @@ export type IsStringLiteral<S> = IfNotAnyOrNever<S,
121
121
  export type _IsStringLiteral<S> =
122
122
  // If `T` is an infinite string type (e.g., `on${string}`), `Record<T, never>` produces an index signature,
123
123
  // and since `{}` extends index signatures, the result becomes `false`.
124
- S extends string
125
- ? {} extends Record<S, never>
126
- ? false
127
- : true
128
- : false;
124
+ S extends string
125
+ ? {} extends Record<S, never>
126
+ ? false
127
+ : true
128
+ : false;
129
129
 
130
130
  /**
131
131
  Returns a boolean for whether the given type is a `number` or `bigint` [literal type](https://www.typescriptlang.org/docs/handbook/2/everyday-types.html#literal-types).
@@ -21,20 +21,20 @@ export type IsUnion<T> = InternalIsUnion<T>;
21
21
  The actual implementation of `IsUnion`.
22
22
  */
23
23
  type InternalIsUnion<T, U = T> =
24
- (
25
- IsNever<T> extends true
26
- ? false
27
- : T extends any
28
- ? IsEqual<U, T> extends true
29
- ? false
30
- : true
31
- : never
32
- ) extends infer Result
24
+ (
25
+ IsNever<T> extends true
26
+ ? false
27
+ : T extends any
28
+ ? IsEqual<U, T> extends true
29
+ ? false
30
+ : true
31
+ : never
32
+ ) extends infer Result
33
33
  // In some cases `Result` will return `false | true` which is `boolean`,
34
34
  // that means `T` has at least two types and it's a union type,
35
35
  // so we will return `true` instead of `boolean`.
36
- ? boolean extends Result ? true
37
- : Result
38
- : never; // Should never happen
36
+ ? boolean extends Result ? true
37
+ : Result
38
+ : never; // Should never happen
39
39
 
40
40
  export {};
@@ -57,10 +57,10 @@ type Fruit = IterableElement<typeof fruits>;
57
57
  @category Iterable
58
58
  */
59
59
  export type IterableElement<TargetIterable> =
60
- TargetIterable extends Iterable<infer ElementType> ?
61
- ElementType :
62
- TargetIterable extends AsyncIterable<infer ElementType> ?
63
- ElementType :
64
- never;
60
+ TargetIterable extends Iterable<infer ElementType>
61
+ ? ElementType
62
+ : TargetIterable extends AsyncIterable<infer ElementType>
63
+ ? ElementType
64
+ : never;
65
65
 
66
66
  export {};
@@ -98,13 +98,13 @@ export type Jsonify<T> = IsAny<T> extends true
98
98
  ? null
99
99
  : T extends JsonPrimitive
100
100
  ? T
101
- : // Any object with toJSON is special case
102
- T extends {toJSON(): infer J}
101
+ // Any object with toJSON is special case
102
+ : T extends {toJSON(): infer J}
103
103
  ? (() => J) extends () => JsonValue // Is J assignable to JsonValue?
104
104
  ? J // Then T is Jsonable and its Jsonable value is J
105
105
  : Jsonify<J> // Maybe if we look a level deeper we'll find a JsonValue
106
- : // Instanced primitives are objects
107
- T extends Number
106
+ // Instanced primitives are objects
107
+ : T extends Number
108
108
  ? number
109
109
  : T extends String
110
110
  ? string
@@ -15,6 +15,7 @@ import type {KebabCase} from 'type-fest';
15
15
 
16
16
  const someVariable: KebabCase<'fooBar'> = 'foo-bar';
17
17
  const someVariableNoSplitOnNumbers: KebabCase<'p2pNetwork', {splitOnNumbers: false}> = 'p2p-network';
18
+ const someVariableWithPunctuation: KebabCase<'div.card::after', {splitOnPunctuation: true}> = 'div-card-after';
18
19
 
19
20
  // Advanced
20
21
 
@@ -51,6 +51,13 @@ const splitOnNumbers: KebabCasedPropertiesDeep<{line1: {line2: [{line3: string}]
51
51
  ],
52
52
  },
53
53
  };
54
+
55
+ const splitOnPunctuation: KebabCasedPropertiesDeep<{'user@info': {'user::id': number; 'user::name': string}}, {splitOnPunctuation: true}> = {
56
+ 'user-info': {
57
+ 'user-id': 1,
58
+ 'user-name': 'Tom',
59
+ },
60
+ };
54
61
  ```
55
62
 
56
63
  @category Change case
@@ -4,7 +4,7 @@ import type {ApplyDefaultOptions} from './internal/index.d.ts';
4
4
  import type {WordsOptions} from './words.d.ts';
5
5
 
6
6
  /**
7
- Convert object properties to kebab case but not recursively.
7
+ Convert top-level object properties to kebab case.
8
8
 
9
9
  This can be useful when, for example, converting some API types from a different style.
10
10
 
@@ -28,6 +28,10 @@ const result: KebabCasedProperties<User> = {
28
28
  const splitOnNumbers: KebabCasedProperties<{line1: string}, {splitOnNumbers: true}> = {
29
29
  'line-1': 'string',
30
30
  };
31
+
32
+ const splitOnPunctuation: KebabCasedProperties<{'foo::bar': string}, {splitOnPunctuation: true}> = {
33
+ 'foo-bar': 'string',
34
+ };
31
35
  ```
32
36
 
33
37
  @category Change case
@@ -38,7 +38,7 @@ type AllKeys = KeysOfUnion<Union>;
38
38
  @category Object
39
39
  */
40
40
  export type KeysOfUnion<ObjectType> =
41
- // Hack to fix https://github.com/sindresorhus/type-fest/issues/1008
42
- keyof UnionToIntersection<ObjectType extends unknown ? Record<keyof ObjectType, never> : never>;
41
+ // Hack to fix https://github.com/sindresorhus/type-fest/issues/1008
42
+ keyof UnionToIntersection<ObjectType extends unknown ? Record<keyof ObjectType, never> : never>;
43
43
 
44
44
  export {};
@@ -1,7 +1,7 @@
1
1
  import type {GreaterThan} from './greater-than.d.ts';
2
2
 
3
3
  /**
4
- Returns a boolean for whether a given number is less than or equal to another number.
4
+ Returns a boolean for whether a given number is less than or equal to another number.
5
5
 
6
6
  @example
7
7
  ```
@@ -16,9 +16,45 @@ type B = LessThanOrEqual<1, 1>;
16
16
  type C = LessThanOrEqual<1, 5>;
17
17
  //=> true
18
18
  ```
19
+
20
+ Note: If either argument is the non-literal `number` type, the result is `boolean`.
21
+
22
+ @example
23
+ ```
24
+ import type {LessThanOrEqual} from 'type-fest';
25
+
26
+ type A = LessThanOrEqual<number, 1>;
27
+ //=> boolean
28
+
29
+ type B = LessThanOrEqual<1, number>;
30
+ //=> boolean
31
+
32
+ type C = LessThanOrEqual<number, number>;
33
+ //=> boolean
34
+ ```
35
+
36
+ @example
37
+ ```
38
+ import type {LessThanOrEqual} from 'type-fest';
39
+
40
+ // Use `LessThanOrEqual` to constrain a function parameter to non-positive numbers.
41
+ declare function setNonPositive<N extends number>(value: LessThanOrEqual<N, 0> extends true ? N : never): void;
42
+
43
+ setNonPositive(0); // ✅ Allowed
44
+ setNonPositive(-1); // ✅ Allowed
45
+
46
+ // @ts-expect-error
47
+ setNonPositive(1);
48
+
49
+ // @ts-expect-error
50
+ setNonPositive(2);
51
+ ```
19
52
  */
20
- export type LessThanOrEqual<A extends number, B extends number> = number extends A | B
21
- ? never
22
- : GreaterThan<A, B> extends true ? false : true;
53
+ export type LessThanOrEqual<A extends number, B extends number> =
54
+ GreaterThan<A, B> extends infer Result
55
+ ? Result extends true
56
+ ? false
57
+ : true
58
+ : never; // Should never happen
23
59
 
24
60
  export {};
@@ -16,10 +16,42 @@ type B = LessThan<1, 1>;
16
16
  type C = LessThan<1, 5>;
17
17
  //=> true
18
18
  ```
19
+
20
+ Note: If either argument is the non-literal `number` type, the result is `boolean`.
21
+
22
+ @example
23
+ ```
24
+ import type {LessThan} from 'type-fest';
25
+
26
+ type A = LessThan<number, 1>;
27
+ //=> boolean
28
+
29
+ type B = LessThan<1, number>;
30
+ //=> boolean
31
+
32
+ type C = LessThan<number, number>;
33
+ //=> boolean
34
+ ```
35
+
36
+ @example
37
+ ```
38
+ import type {LessThan} from 'type-fest';
39
+
40
+ // Use `LessThan` to constrain a function parameter to negative numbers.
41
+ declare function setNegative<N extends number>(value: LessThan<N, 0> extends true ? N : never): void;
42
+
43
+ setNegative(-1); // ✅ Allowed
44
+ setNegative(-2); // ✅ Allowed
45
+
46
+ // @ts-expect-error
47
+ setNegative(0);
48
+
49
+ // @ts-expect-error
50
+ setNegative(1);
51
+ ```
19
52
  */
20
- export type LessThan<A extends number, B extends number> = number extends A | B
21
- ? never
22
- : GreaterThanOrEqual<A, B> extends infer Result
53
+ export type LessThan<A extends number, B extends number> =
54
+ GreaterThanOrEqual<A, B> extends infer Result
23
55
  ? Result extends true
24
56
  ? false
25
57
  : true
@@ -1,5 +1,5 @@
1
1
  /**
2
- Given a [literal type](https://www.typescriptlang.org/docs/handbook/2/everyday-types.html#literal-types) return the {@link Primitive | primitive type} it belongs to, or `never` if it's not a primitive.
2
+ Given a [literal type](https://www.typescriptlang.org/docs/handbook/2/everyday-types.html#literal-types) return the [primitive type](https://developer.mozilla.org/en-US/docs/Glossary/Primitive) it belongs to, or `never` if it's not a primitive.
3
3
 
4
4
  Use-case: Working with generic types that may be literal types.
5
5
 
@@ -3,7 +3,7 @@ import type {Primitive} from './primitive.d.ts';
3
3
  export type _LiteralStringUnion<T> = LiteralUnion<T, string>;
4
4
 
5
5
  /**
6
- Allows creating a union type by combining primitive types and literal types without sacrificing auto-completion in IDEs for the literal type part of the union.
6
+ Create a union type by combining primitive types and literal types without sacrificing auto-completion in IDEs for the literal type part of the union.
7
7
 
8
8
  Currently, when a union type of a primitive type is combined with literal types, TypeScript loses all information about the combined literals. Thus, when such type is used in an IDE with autocompletion, no suggestions are made for the declared literals.
9
9
 
@@ -38,8 +38,8 @@ exclusiveOptions = {exclusive1: true, exclusive2: 'hi'};
38
38
  @category Object
39
39
  */
40
40
  export type MergeExclusive<FirstType, SecondType> =
41
- (FirstType | SecondType) extends object ?
42
- (Without<FirstType, SecondType> & SecondType) | (Without<SecondType, FirstType> & FirstType) :
43
- FirstType | SecondType;
41
+ (FirstType | SecondType) extends object
42
+ ? (Without<FirstType, SecondType> & SecondType) | (Without<SecondType, FirstType> & FirstType)
43
+ : FirstType | SecondType;
44
44
 
45
45
  export {};
package/source/merge.d.ts CHANGED
@@ -12,6 +12,31 @@ type SimpleMerge<Destination, Source> = Simplify<{
12
12
  /**
13
13
  Merge two types into a new type. Keys of the second type overrides keys of the first type.
14
14
 
15
+ This is different from the TypeScript `&` (intersection) operator. With `&`, conflicting property types are intersected, which often results in `never`. For example, `{a: string} & {a: number}` makes `a` become `string & number`, which resolves to `never`. With `Merge`, the second type's keys cleanly override the first, so `Merge<{a: string}, {a: number}>` gives `{a: number}` as expected. `Merge` also produces a flattened type (via `Simplify`), making it more readable in IDE tooltips compared to `A & B`.
16
+
17
+ @example
18
+ ```
19
+ import type {Merge} from 'type-fest';
20
+
21
+ type Foo = {
22
+ a: string;
23
+ b: number;
24
+ };
25
+
26
+ type Bar = {
27
+ a: number; // Conflicts with Foo['a']
28
+ c: boolean;
29
+ };
30
+
31
+ // With `&`, `a` becomes `string & number` which is `never`. Not what you want.
32
+ type WithIntersection = (Foo & Bar)['a'];
33
+ //=> never
34
+
35
+ // With `Merge`, `a` is cleanly overridden to `number`.
36
+ type WithMerge = Merge<Foo, Bar>['a'];
37
+ //=> number
38
+ ```
39
+
15
40
  @example
16
41
  ```
17
42
  import type {Merge} from 'type-fest';
@@ -4,7 +4,7 @@ import type {IsEqual} from './is-equal.d.ts';
4
4
  type Recursive<T> = Array<Recursive<T>>;
5
5
 
6
6
  /**
7
- Creates a type that represents a multidimensional array of the given type and dimension.
7
+ Create a type that represents a multidimensional array of the given type and dimension.
8
8
 
9
9
  Use-cases:
10
10
  - Return a n-dimensional array from functions.
@@ -4,7 +4,7 @@ import type {IsEqual} from './is-equal.d.ts';
4
4
  type Recursive<T> = ReadonlyArray<Recursive<T>>;
5
5
 
6
6
  /**
7
- Creates a type that represents a multidimensional readonly array that of the given type and dimension.
7
+ Create a type that represents a multidimensional readonly array of the given type and dimension.
8
8
 
9
9
  Use-cases:
10
10
  - Return a n-dimensional array from functions.
@@ -0,0 +1,102 @@
1
+ import type {BuiltIns, HasMultipleCallSignatures} from './internal/type.d.ts';
2
+ import type {IsNever} from './is-never.d.ts';
3
+ import type {Simplify} from './simplify.d.ts';
4
+
5
+ /**
6
+ Recursively removes `null` and `undefined` from the specified type.
7
+
8
+ Use-cases:
9
+ - Normalizing data received from external sources where `null`/`undefined` have been cleaned.
10
+ - Creating non-nullable variants of deeply nested types.
11
+
12
+ NOTE: Optional modifiers (`?`) are not removed from properties. For example, `NonNullableDeep<{foo?: string | null | undefined}>` will result in `{foo?: string}`. To remove both optional modifiers and nullables, use {@link RequiredDeep} in conjunction with this type.
13
+
14
+ @example
15
+ ```
16
+ import type {NonNullableDeep} from 'type-fest';
17
+
18
+ type UserDraft = {
19
+ name: string | null;
20
+ address: {
21
+ city: string | undefined;
22
+ postalCode: string | null;
23
+ landmark?: string | undefined;
24
+ };
25
+ tags: Array<string | null>;
26
+ visits: Map<string | null, {
27
+ date: Date | null;
28
+ notes: Set<string | undefined>;
29
+ }>;
30
+ };
31
+
32
+ type User = NonNullableDeep<UserDraft>;
33
+ //=> {
34
+ // name: string;
35
+ // address: {
36
+ // city: string;
37
+ // postalCode: string;
38
+ // landmark?: string;
39
+ // };
40
+ // tags: string[];
41
+ // visits: Map<string, {
42
+ // date: Date;
43
+ // notes: Set<string>;
44
+ // }>;
45
+ // }
46
+ ```
47
+
48
+ @example
49
+ ```
50
+ import type {NonNullableDeep} from 'type-fest';
51
+
52
+ type ArrayExample = NonNullableDeep<[{a: number | undefined}, ...Array<{b: string | null}>]>;
53
+ //=> [{a: number}, ...{b: string}[]]
54
+
55
+ type MapExample = NonNullableDeep<{a: Map<{a: string | null}, {c: number | undefined}>}>;
56
+ //=> {a: Map<{a: string}, {c: number}>}
57
+
58
+ type SetExample = NonNullableDeep<Set<{a: string | null}> | null | undefined>;
59
+ //=> Set<{a: string}>
60
+
61
+ type PromiseExample = NonNullableDeep<{a: Promise<{b: string | null}>}>;
62
+ //=> {a: Promise<{b: string}>}
63
+
64
+ type FunctionExample = NonNullableDeep<(a: string | null) => number | undefined>;
65
+ //=> (a: string) => number
66
+ ```
67
+
68
+ @category Utilities
69
+ @category Object
70
+ @category Array
71
+ @category Set
72
+ @category Map
73
+ */
74
+ export type NonNullableDeep<T> =
75
+ T extends BuiltIns | (new (...arguments_: any[]) => unknown)
76
+ ? Exclude<T, null | undefined> // `Exclude` is used instead of `NonNullable` because `NonNullable<void>` results in `void & {}`.
77
+ : T extends Map<infer KeyType, infer ValueType>
78
+ ? Map<NonNullableDeep<KeyType>, NonNullableDeep<ValueType>>
79
+ : T extends Set<infer ItemType>
80
+ ? Set<NonNullableDeep<ItemType>>
81
+ : T extends ReadonlyMap<infer KeyType, infer ValueType>
82
+ ? ReadonlyMap<NonNullableDeep<KeyType>, NonNullableDeep<ValueType>>
83
+ : T extends ReadonlySet<infer ItemType>
84
+ ? ReadonlySet<NonNullableDeep<ItemType>>
85
+ : T extends WeakMap<infer KeyType, infer ValueType>
86
+ ? WeakMap<NonNullableDeep<KeyType>, NonNullableDeep<ValueType>>
87
+ : T extends WeakSet<infer ItemType>
88
+ ? WeakSet<NonNullableDeep<ItemType>>
89
+ : T extends Promise<infer ValueType>
90
+ ? Promise<NonNullableDeep<ValueType>>
91
+ : T extends (...arguments_: any[]) => unknown
92
+ ? HasMultipleCallSignatures<T> extends true
93
+ ? T
94
+ : ((...arguments_: NonNullableDeep<Parameters<T>>) => NonNullableDeep<ReturnType<T>>)
95
+ & (IsNever<keyof T> extends true
96
+ ? unknown
97
+ : NonNullableDeep<Simplify<T>>) // `Simplify` removes the call signature
98
+ : T extends object
99
+ ? {[P in keyof T]: NonNullableDeep<T[P]>}
100
+ : unknown;
101
+
102
+ export {};
@@ -121,9 +121,9 @@ declare function setPercentage<T extends number>(length: Float<T>): void;
121
121
  @category Numeric
122
122
  */
123
123
  export type Float<T> =
124
- T extends unknown // To distributive type
125
- ? IsFloat<T> extends true ? T : never
126
- : never; // Never happens
124
+ T extends unknown // To distributive type
125
+ ? IsFloat<T> extends true ? T : never
126
+ : never; // Never happens
127
127
 
128
128
  /**
129
129
  A negative (`-∞ < x < 0`) `number` that is not an integer.