@depup/type-fest 5.4.4-depup.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 (201) hide show
  1. package/README.md +25 -0
  2. package/index.d.ts +211 -0
  3. package/license-cc0 +121 -0
  4. package/license-mit +9 -0
  5. package/package.json +85 -0
  6. package/readme.md +1052 -0
  7. package/source/all-extend.d.ts +120 -0
  8. package/source/all-union-fields.d.ts +91 -0
  9. package/source/and.d.ts +81 -0
  10. package/source/array-element.d.ts +46 -0
  11. package/source/array-indices.d.ts +25 -0
  12. package/source/array-reverse.d.ts +84 -0
  13. package/source/array-slice.d.ts +132 -0
  14. package/source/array-splice.d.ts +104 -0
  15. package/source/array-tail.d.ts +70 -0
  16. package/source/array-values.d.ts +24 -0
  17. package/source/arrayable.d.ts +31 -0
  18. package/source/async-return-type.d.ts +28 -0
  19. package/source/asyncify.d.ts +25 -0
  20. package/source/basic.d.ts +38 -0
  21. package/source/camel-case.d.ts +92 -0
  22. package/source/camel-cased-properties-deep.d.ts +99 -0
  23. package/source/camel-cased-properties.d.ts +45 -0
  24. package/source/characters.d.ts +67 -0
  25. package/source/conditional-except.d.ts +47 -0
  26. package/source/conditional-keys.d.ts +63 -0
  27. package/source/conditional-pick-deep.d.ts +120 -0
  28. package/source/conditional-pick.d.ts +46 -0
  29. package/source/conditional-simplify-deep.d.ts +73 -0
  30. package/source/conditional-simplify.d.ts +50 -0
  31. package/source/delimiter-case.d.ts +77 -0
  32. package/source/delimiter-cased-properties-deep.d.ts +108 -0
  33. package/source/delimiter-cased-properties.d.ts +48 -0
  34. package/source/distributed-omit.d.ts +96 -0
  35. package/source/distributed-pick.d.ts +92 -0
  36. package/source/empty-object.d.ts +51 -0
  37. package/source/entries.d.ts +64 -0
  38. package/source/entry.d.ts +67 -0
  39. package/source/exact.d.ts +73 -0
  40. package/source/except.d.ts +112 -0
  41. package/source/exclude-rest-element.d.ts +40 -0
  42. package/source/exclude-strict.d.ts +51 -0
  43. package/source/exclusify-union.d.ts +147 -0
  44. package/source/extends-strict.d.ts +44 -0
  45. package/source/extract-rest-element.d.ts +30 -0
  46. package/source/extract-strict.d.ts +51 -0
  47. package/source/find-global-type.d.ts +68 -0
  48. package/source/fixed-length-array.d.ts +97 -0
  49. package/source/get.d.ts +227 -0
  50. package/source/global-this.d.ts +24 -0
  51. package/source/globals/index.d.ts +3 -0
  52. package/source/globals/observable-like.d.ts +78 -0
  53. package/source/greater-than-or-equal.d.ts +30 -0
  54. package/source/greater-than.d.ts +58 -0
  55. package/source/has-optional-keys.d.ts +23 -0
  56. package/source/has-readonly-keys.d.ts +23 -0
  57. package/source/has-required-keys.d.ts +61 -0
  58. package/source/has-writable-keys.d.ts +23 -0
  59. package/source/if-any.d.ts +28 -0
  60. package/source/if-empty-object.d.ts +30 -0
  61. package/source/if-never.d.ts +28 -0
  62. package/source/if-null.d.ts +28 -0
  63. package/source/if-unknown.d.ts +28 -0
  64. package/source/if.d.ts +102 -0
  65. package/source/includes.d.ts +24 -0
  66. package/source/int-closed-range.d.ts +47 -0
  67. package/source/int-range.d.ts +69 -0
  68. package/source/internal/array.d.ts +151 -0
  69. package/source/internal/characters.d.ts +65 -0
  70. package/source/internal/enforce-optional.d.ts +49 -0
  71. package/source/internal/index.d.ts +11 -0
  72. package/source/internal/keys.d.ts +100 -0
  73. package/source/internal/numeric.d.ts +151 -0
  74. package/source/internal/object.d.ts +292 -0
  75. package/source/internal/string.d.ts +202 -0
  76. package/source/internal/tuple.d.ts +79 -0
  77. package/source/internal/type.d.ts +164 -0
  78. package/source/invariant-of.d.ts +85 -0
  79. package/source/is-any.d.ts +31 -0
  80. package/source/is-equal.d.ts +42 -0
  81. package/source/is-float.d.ts +43 -0
  82. package/source/is-integer.d.ts +60 -0
  83. package/source/is-literal.d.ts +315 -0
  84. package/source/is-lowercase.d.ts +38 -0
  85. package/source/is-never.d.ts +56 -0
  86. package/source/is-null.d.ts +22 -0
  87. package/source/is-nullable.d.ts +30 -0
  88. package/source/is-optional-key-of.d.ts +51 -0
  89. package/source/is-optional.d.ts +28 -0
  90. package/source/is-readonly-key-of.d.ts +55 -0
  91. package/source/is-required-key-of.d.ts +51 -0
  92. package/source/is-tuple.d.ts +92 -0
  93. package/source/is-undefined.d.ts +22 -0
  94. package/source/is-union.d.ts +40 -0
  95. package/source/is-unknown.d.ts +43 -0
  96. package/source/is-uppercase.d.ts +38 -0
  97. package/source/is-writable-key-of.d.ts +51 -0
  98. package/source/iterable-element.d.ts +66 -0
  99. package/source/join.d.ts +79 -0
  100. package/source/json-value.d.ts +33 -0
  101. package/source/jsonifiable.d.ts +37 -0
  102. package/source/jsonify.d.ts +127 -0
  103. package/source/kebab-case.d.ts +46 -0
  104. package/source/kebab-cased-properties-deep.d.ts +65 -0
  105. package/source/kebab-cased-properties.d.ts +42 -0
  106. package/source/key-as-string.d.ts +27 -0
  107. package/source/keys-of-union.d.ts +44 -0
  108. package/source/last-array-element.d.ts +36 -0
  109. package/source/less-than-or-equal.d.ts +24 -0
  110. package/source/less-than.d.ts +28 -0
  111. package/source/literal-to-primitive-deep.d.ts +71 -0
  112. package/source/literal-to-primitive.d.ts +38 -0
  113. package/source/literal-union.d.ts +39 -0
  114. package/source/merge-deep.d.ts +495 -0
  115. package/source/merge-exclusive.d.ts +45 -0
  116. package/source/merge.d.ts +62 -0
  117. package/source/multidimensional-array.d.ts +38 -0
  118. package/source/multidimensional-readonly-array.d.ts +38 -0
  119. package/source/non-empty-object.d.ts +38 -0
  120. package/source/non-empty-string.d.ts +32 -0
  121. package/source/non-empty-tuple.d.ts +24 -0
  122. package/source/numeric.d.ts +226 -0
  123. package/source/object-merge.d.ts +194 -0
  124. package/source/omit-deep.d.ts +154 -0
  125. package/source/omit-index-signature.d.ts +98 -0
  126. package/source/opaque.d.ts +3 -0
  127. package/source/optional-keys-of.d.ts +46 -0
  128. package/source/or.d.ts +89 -0
  129. package/source/override-properties.d.ts +43 -0
  130. package/source/package-json.d.ts +710 -0
  131. package/source/partial-deep.d.ts +155 -0
  132. package/source/partial-on-undefined-deep.d.ts +81 -0
  133. package/source/pascal-case.d.ts +51 -0
  134. package/source/pascal-cased-properties-deep.d.ts +72 -0
  135. package/source/pascal-cased-properties.d.ts +42 -0
  136. package/source/paths.d.ts +241 -0
  137. package/source/pick-deep.d.ts +152 -0
  138. package/source/pick-index-signature.d.ts +52 -0
  139. package/source/primitive.d.ts +15 -0
  140. package/source/promisable.d.ts +27 -0
  141. package/source/readonly-deep.d.ts +116 -0
  142. package/source/readonly-keys-of.d.ts +38 -0
  143. package/source/readonly-tuple.d.ts +34 -0
  144. package/source/remove-prefix.d.ts +132 -0
  145. package/source/replace.d.ts +87 -0
  146. package/source/require-all-or-none.d.ts +54 -0
  147. package/source/require-at-least-one.d.ts +50 -0
  148. package/source/require-exactly-one.d.ts +48 -0
  149. package/source/require-one-or-none.d.ts +49 -0
  150. package/source/required-deep.d.ts +76 -0
  151. package/source/required-keys-of.d.ts +38 -0
  152. package/source/schema.d.ts +119 -0
  153. package/source/screaming-snake-case.d.ts +30 -0
  154. package/source/set-field-type.d.ts +67 -0
  155. package/source/set-non-nullable-deep.d.ts +85 -0
  156. package/source/set-non-nullable.d.ts +41 -0
  157. package/source/set-optional.d.ts +46 -0
  158. package/source/set-parameter-type.d.ts +125 -0
  159. package/source/set-readonly.d.ts +44 -0
  160. package/source/set-required-deep.d.ts +64 -0
  161. package/source/set-required.d.ts +79 -0
  162. package/source/set-return-type.d.ts +31 -0
  163. package/source/shared-union-fields-deep.d.ts +180 -0
  164. package/source/shared-union-fields.d.ts +79 -0
  165. package/source/simplify-deep.d.ts +117 -0
  166. package/source/simplify.d.ts +61 -0
  167. package/source/single-key-object.d.ts +28 -0
  168. package/source/snake-case.d.ts +47 -0
  169. package/source/snake-cased-properties-deep.d.ts +65 -0
  170. package/source/snake-cased-properties.d.ts +42 -0
  171. package/source/split-on-rest-element.d.ts +106 -0
  172. package/source/split.d.ts +90 -0
  173. package/source/spread.d.ts +82 -0
  174. package/source/string-repeat.d.ts +49 -0
  175. package/source/string-slice.d.ts +39 -0
  176. package/source/stringified.d.ts +25 -0
  177. package/source/structured-cloneable.d.ts +89 -0
  178. package/source/subtract.d.ts +86 -0
  179. package/source/sum.d.ts +81 -0
  180. package/source/tagged-union.d.ts +53 -0
  181. package/source/tagged.d.ts +263 -0
  182. package/source/trim.d.ts +29 -0
  183. package/source/tsconfig-json.d.ts +1324 -0
  184. package/source/tuple-of.d.ts +80 -0
  185. package/source/tuple-to-object.d.ts +47 -0
  186. package/source/tuple-to-union.d.ts +54 -0
  187. package/source/typed-array.d.ts +19 -0
  188. package/source/undefined-on-partial-deep.d.ts +83 -0
  189. package/source/union-to-intersection.d.ts +35 -0
  190. package/source/union-to-tuple.d.ts +58 -0
  191. package/source/unknown-array.d.ts +27 -0
  192. package/source/unknown-map.d.ts +26 -0
  193. package/source/unknown-record.d.ts +33 -0
  194. package/source/unknown-set.d.ts +26 -0
  195. package/source/unwrap-partial.d.ts +33 -0
  196. package/source/value-of.d.ts +24 -0
  197. package/source/words.d.ts +122 -0
  198. package/source/writable-deep.d.ts +84 -0
  199. package/source/writable-keys-of.d.ts +34 -0
  200. package/source/writable.d.ts +72 -0
  201. package/source/xor.d.ts +83 -0
@@ -0,0 +1,92 @@
1
+ import type {If} from './if.d.ts';
2
+ import type {ApplyDefaultOptions} from './internal/index.d.ts';
3
+ import type {IsAny} from './is-any.d.ts';
4
+ import type {IsNever} from './is-never.d.ts';
5
+ import type {UnknownArray} from './unknown-array.d.ts';
6
+
7
+ /**
8
+ @see {@link IsTuple}
9
+ */
10
+ export type IsTupleOptions = {
11
+ /**
12
+ Consider only fixed length arrays as tuples.
13
+
14
+ - When set to `true` (default), arrays with rest elements (e.g., `[1, ...number[]]`) are _not_ considered as tuples.
15
+ - When set to `false`, arrays with at least one non-rest element (e.g., `[1, ...number[]]`) are considered as tuples.
16
+
17
+ @default true
18
+
19
+ @example
20
+ ```ts
21
+ import type {IsTuple} from 'type-fest';
22
+
23
+ type Example1 = IsTuple<[number, ...number[]], {fixedLengthOnly: true}>;
24
+ //=> false
25
+
26
+ type Example2 = IsTuple<[number, ...number[]], {fixedLengthOnly: false}>;
27
+ //=> true
28
+ ```
29
+ */
30
+ fixedLengthOnly?: boolean;
31
+ };
32
+
33
+ type DefaultIsTupleOptions = {
34
+ fixedLengthOnly: true;
35
+ };
36
+
37
+ /**
38
+ Returns a boolean for whether the given array is a tuple.
39
+
40
+ Use-case:
41
+ - If you want to make a conditional branch based on the result of whether an array is a tuple or not.
42
+
43
+ Note: `IsTuple` returns `boolean` when instantiated with a union of tuple and non-tuple (e.g., `IsTuple<[1, 2] | number[]>`).
44
+
45
+ @example
46
+ ```ts
47
+ import type {IsTuple} from 'type-fest';
48
+
49
+ type Tuple = IsTuple<[1, 2, 3]>;
50
+ //=> true
51
+
52
+ type NotTuple = IsTuple<number[]>;
53
+ //=> false
54
+
55
+ type TupleWithOptionalItems = IsTuple<[1?, 2?]>;
56
+ //=> true
57
+
58
+ type RestItemsNotAllowed = IsTuple<[1, 2, ...number[]]>;
59
+ //=> false
60
+
61
+ type RestItemsAllowed = IsTuple<[1, 2, ...number[]], {fixedLengthOnly: false}>;
62
+ //=> true
63
+ ```
64
+
65
+ @see {@link IsTupleOptions}
66
+
67
+ @category Type Guard
68
+ @category Utilities
69
+ */
70
+ export type IsTuple<
71
+ TArray extends UnknownArray,
72
+ Options extends IsTupleOptions = {},
73
+ > =
74
+ _IsTuple<TArray, ApplyDefaultOptions<IsTupleOptions, DefaultIsTupleOptions, Options>>;
75
+
76
+ type _IsTuple<
77
+ TArray extends UnknownArray,
78
+ Options extends Required<IsTupleOptions>,
79
+ > =
80
+ If<IsAny<TArray>, boolean, If<IsNever<TArray>, false,
81
+ TArray extends unknown // For distributing `TArray`
82
+ ? number extends TArray['length']
83
+ ? Options['fixedLengthOnly'] extends false
84
+ ? If<IsNever<keyof TArray & `${number}`>,
85
+ TArray extends readonly [...any, any] ? true : false, // To handle cases where a non-rest element follows a rest element, e.g., `[...number[], number]`
86
+ true>
87
+ : false
88
+ : true
89
+ : false
90
+ >>;
91
+
92
+ export {};
@@ -0,0 +1,22 @@
1
+ /**
2
+ Returns a boolean for whether the given type is `undefined`.
3
+
4
+ @example
5
+ ```
6
+ import type {IsUndefined} from 'type-fest';
7
+
8
+ type UndefinedFallback<T, Fallback> = IsUndefined<T> extends true ? Fallback : T;
9
+
10
+ type Example1 = UndefinedFallback<undefined, string>;
11
+ //=> string
12
+
13
+ type Example2 = UndefinedFallback<number, string>;
14
+ //=> number
15
+ ```
16
+
17
+ @category Type Guard
18
+ @category Utilities
19
+ */
20
+ export type IsUndefined<T> = [T] extends [undefined] ? true : false;
21
+
22
+ export {};
@@ -0,0 +1,40 @@
1
+ import type {IsNever} from './is-never.d.ts';
2
+ import type {IsEqual} from './is-equal.d.ts';
3
+
4
+ /**
5
+ Returns a boolean for whether the given type is a union.
6
+
7
+ @example
8
+ ```
9
+ import type {IsUnion} from 'type-fest';
10
+
11
+ type A = IsUnion<string | number>;
12
+ //=> true
13
+
14
+ type B = IsUnion<string>;
15
+ //=> false
16
+ ```
17
+ */
18
+ export type IsUnion<T> = InternalIsUnion<T>;
19
+
20
+ /**
21
+ The actual implementation of `IsUnion`.
22
+ */
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
33
+ // In some cases `Result` will return `false | true` which is `boolean`,
34
+ // that means `T` has at least two types and it's a union type,
35
+ // so we will return `true` instead of `boolean`.
36
+ ? boolean extends Result ? true
37
+ : Result
38
+ : never; // Should never happen
39
+
40
+ export {};
@@ -0,0 +1,43 @@
1
+ import type {IsNull} from './is-null.d.ts';
2
+
3
+ /**
4
+ Returns a boolean for whether the given type is `unknown`.
5
+
6
+ @link https://github.com/dsherret/conditional-type-checks/pull/16
7
+
8
+ Useful in type utilities, such as when dealing with unknown data from API calls.
9
+
10
+ @example
11
+ ```
12
+ import type {IsUnknown} from 'type-fest';
13
+
14
+ type A = IsUnknown<unknown>;
15
+ //=> true
16
+
17
+ type B = IsUnknown<any>;
18
+ //=> false
19
+
20
+ type C = IsUnknown<never>;
21
+ //=> false
22
+
23
+ type D = IsUnknown<unknown[]>;
24
+ //=> false
25
+
26
+ type E = IsUnknown<object>;
27
+ //=> false
28
+
29
+ type F = IsUnknown<string>;
30
+ //=> false
31
+ ```
32
+
33
+ @category Utilities
34
+ */
35
+ export type IsUnknown<T> = (
36
+ unknown extends T // `T` can be `unknown` or `any`
37
+ ? IsNull<T> extends false // `any` can be `null`, but `unknown` can't be
38
+ ? true
39
+ : false
40
+ : false
41
+ );
42
+
43
+ export {};
@@ -0,0 +1,38 @@
1
+ import type {AllExtend} from './all-extend.d.ts';
2
+
3
+ /**
4
+ Returns a boolean for whether the given string literal is uppercase.
5
+
6
+ @example
7
+ ```
8
+ import type {IsUppercase} from 'type-fest';
9
+
10
+ type A = IsUppercase<'ABC'>;
11
+ //=> true
12
+
13
+ type B = IsUppercase<'Abc'>;
14
+ //=> false
15
+
16
+ type C = IsUppercase<string>;
17
+ //=> boolean
18
+ ```
19
+ */
20
+ export type IsUppercase<S extends string> = AllExtend<_IsUppercase<S>, true>;
21
+
22
+ /**
23
+ Loops through each part in the string and returns a boolean array indicating whether each part is uppercase.
24
+ */
25
+ type _IsUppercase<S extends string, Accumulator extends boolean[] = []> = S extends `${infer First}${infer Rest}`
26
+ ? _IsUppercase<Rest, [...Accumulator, IsUppercaseHelper<First>]>
27
+ : [...Accumulator, IsUppercaseHelper<S>];
28
+
29
+ /**
30
+ Returns a boolean for whether an individual part of the string is uppercase.
31
+ */
32
+ type IsUppercaseHelper<S extends string> = S extends Uppercase<string>
33
+ ? true
34
+ : S extends Lowercase<string> | Uncapitalize<string> | `${string}${Lowercase<string>}${string}`
35
+ ? false
36
+ : boolean;
37
+
38
+ export {};
@@ -0,0 +1,51 @@
1
+ import type {IsReadonlyKeyOf} from './is-readonly-key-of.d.ts';
2
+ import type {Not} from './internal/type.d.ts';
3
+ import type {IsAny} from './is-any.d.ts';
4
+
5
+ /**
6
+ Returns a boolean for whether the given key is a writable key of type.
7
+
8
+ This is useful when writing utility types or schema validators that need to differentiate `writable` keys.
9
+
10
+ @example
11
+ ```
12
+ import type {IsWritableKeyOf} from 'type-fest';
13
+
14
+ type User = {
15
+ name: string;
16
+ surname: string;
17
+
18
+ readonly id: number;
19
+ };
20
+
21
+ type Admin = {
22
+ name: string;
23
+ id: string;
24
+ };
25
+
26
+ type T1 = IsWritableKeyOf<User, 'name'>;
27
+ //=> true
28
+
29
+ type T2 = IsWritableKeyOf<User, 'id'>;
30
+ //=> false
31
+
32
+ type T3 = IsWritableKeyOf<User, 'name' | 'id'>;
33
+ //=> boolean
34
+
35
+ type T4 = IsWritableKeyOf<User | Admin, 'name'>;
36
+ //=> true
37
+
38
+ type T5 = IsWritableKeyOf<User | Admin, 'id'>;
39
+ //=> boolean
40
+ ```
41
+
42
+ @category Type Guard
43
+ @category Utilities
44
+ */
45
+ export type IsWritableKeyOf<Type extends object, Key extends keyof Type> =
46
+ IsAny<Type | Key> extends true ? never
47
+ : Key extends keyof Type
48
+ ? Not<IsReadonlyKeyOf<Type, Key>>
49
+ : false;
50
+
51
+ export {};
@@ -0,0 +1,66 @@
1
+ /**
2
+ Get the element type of an `Iterable`/`AsyncIterable`. For example, `Array`, `Set`, `Map`, generator, stream, etc.
3
+
4
+ This can be useful, for example, if you want to get the type that is yielded in a generator function. Often the return type of those functions are not specified.
5
+
6
+ This type works with both `Iterable`s and `AsyncIterable`s, so it can be use with synchronous and asynchronous generators.
7
+
8
+ Here is an example of `IterableElement` in action with a generator function:
9
+
10
+ @example
11
+ ```
12
+ import type {IterableElement} from 'type-fest';
13
+
14
+ function * iAmGenerator() {
15
+ yield 1;
16
+ yield 2;
17
+ }
18
+
19
+ type MeNumber = IterableElement<ReturnType<typeof iAmGenerator>>;
20
+ ```
21
+
22
+ And here is an example with an async generator:
23
+
24
+ @example
25
+ ```
26
+ import type {IterableElement} from 'type-fest';
27
+
28
+ async function * iAmGeneratorAsync() {
29
+ yield 'hi';
30
+ yield true;
31
+ }
32
+
33
+ type MeStringOrBoolean = IterableElement<ReturnType<typeof iAmGeneratorAsync>>;
34
+ ```
35
+
36
+ Many types in JavaScript/TypeScript are iterables. This type works on all types that implement those interfaces.
37
+
38
+ An example with an array of strings:
39
+
40
+ @example
41
+ ```
42
+ import type {IterableElement} from 'type-fest';
43
+
44
+ type MeString = IterableElement<string[]>;
45
+ ```
46
+
47
+ @example
48
+ ```
49
+ import type {IterableElement} from 'type-fest';
50
+
51
+ const fruits = new Set(['🍎', '🍌', '🍉'] as const);
52
+
53
+ type Fruit = IterableElement<typeof fruits>;
54
+ //=> '🍎' | '🍌' | '🍉'
55
+ ```
56
+
57
+ @category Iterable
58
+ */
59
+ export type IterableElement<TargetIterable> =
60
+ TargetIterable extends Iterable<infer ElementType> ?
61
+ ElementType :
62
+ TargetIterable extends AsyncIterable<infer ElementType> ?
63
+ ElementType :
64
+ never;
65
+
66
+ export {};
@@ -0,0 +1,79 @@
1
+ // The builtin `join` method supports all these natively in the same way that typescript handles them so we can safely accept all of them.
2
+ type JoinableItem = string | number | bigint | boolean | undefined | null;
3
+
4
+ // `null` and `undefined` are treated uniquely in the built-in join method, in a way that differs from the default `toString` that would result in the type `${undefined}`. That's why we need to handle it specifically with this helper.
5
+ // @see https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Array/join#description
6
+ type NullishCoalesce<
7
+ Value extends JoinableItem,
8
+ Fallback extends string,
9
+ > = Value extends undefined | null ? NonNullable<Value> | Fallback : Value;
10
+
11
+ /**
12
+ Join an array of strings and/or numbers using the given string as a delimiter.
13
+
14
+ Use-case: Defining key paths in a nested object. For example, for dot-notation fields in MongoDB queries.
15
+
16
+ @example
17
+ ```
18
+ import type {Join} from 'type-fest';
19
+
20
+ // Mixed (strings & numbers) items
21
+ const path1 = ['foo', 0, 'baz'].join('.') as Join<['foo', 0, 'baz'], '.'>;
22
+ //=> 'foo.0.baz'
23
+
24
+ // Only string items
25
+ const path2 = ['foo', 'bar', 'baz'].join('.') as Join<['foo', 'bar', 'baz'], '.'>;
26
+ //=> 'foo.bar.baz'
27
+
28
+ // Only number items
29
+ const path3 = [1, 2, 3].join('.') as Join<[1, 2, 3], '.'>;
30
+ //=> '1.2.3'
31
+
32
+ // Only bigint items
33
+ const path4 = [1n, 2n, 3n].join('.') as Join<[1n, 2n, 3n], '.'>;
34
+ //=> '1.2.3'
35
+
36
+ // Only boolean items
37
+ const path5 = [true, false, true].join('.') as Join<[true, false, true], '.'>;
38
+ //=> 'true.false.true'
39
+
40
+ // Contains nullish items
41
+ const path6 = ['foo', undefined, 'baz', null, 'xyz'].join('.') as Join<['foo', undefined, 'baz', null, 'xyz'], '.'>;
42
+ //=> 'foo..baz..xyz'
43
+
44
+ // Partial tuple shapes (rest param last)
45
+ const path7 = ['prefix'].join('.') as Join<['prefix', ...string[]], '.'>;
46
+ //=> `prefix.${string}`
47
+
48
+ // Partial tuple shapes (rest param first)
49
+ const path8 = ['suffix'].join('.') as Join<[...string[], 'suffix'], '.'>;
50
+ //=> `${string}.suffix`
51
+
52
+ // Tuples items with nullish unions
53
+ const path9 = ['hello', 'world'].join('.') as Join<['hello' | undefined, 'world' | null], '.'>;
54
+ //=> '.' | '.world' | 'hello.' | 'hello.world'
55
+ ```
56
+
57
+ @category Array
58
+ @category Template literal
59
+ */
60
+ export type Join<
61
+ Items extends readonly JoinableItem[],
62
+ Delimiter extends string,
63
+ > = Items extends readonly []
64
+ ? ''
65
+ : Items extends readonly [JoinableItem?]
66
+ ? `${NullishCoalesce<Items[0], ''>}`
67
+ : Items extends readonly [
68
+ infer First extends JoinableItem,
69
+ ...infer Tail extends readonly JoinableItem[],
70
+ ]
71
+ ? `${NullishCoalesce<First, ''>}${Delimiter}${Join<Tail, Delimiter>}`
72
+ : Items extends readonly [
73
+ ...infer Head extends readonly JoinableItem[],
74
+ infer Last extends JoinableItem,
75
+ ]
76
+ ? `${Join<Head, Delimiter>}${Delimiter}${NullishCoalesce<Last, ''>}`
77
+ : string;
78
+
79
+ export {};
@@ -0,0 +1,33 @@
1
+ /**
2
+ Matches a JSON object.
3
+
4
+ This type can be useful to enforce some input to be JSON-compatible or as a super-type to be extended from. Don't use this as a direct return type as the user would have to double-cast it: `jsonObject as unknown as CustomResponse`. Instead, you could extend your CustomResponse type from it to ensure your type only uses JSON-compatible types: `interface CustomResponse extends JsonObject { … }`.
5
+
6
+ @category JSON
7
+ */
8
+ export type JsonObject = {[Key in string]: JsonValue};
9
+
10
+ /**
11
+ Matches a JSON array.
12
+
13
+ @category JSON
14
+ */
15
+ export type JsonArray = JsonValue[] | readonly JsonValue[];
16
+
17
+ /**
18
+ Matches any valid JSON primitive value.
19
+
20
+ @category JSON
21
+ */
22
+ export type JsonPrimitive = string | number | boolean | null;
23
+
24
+ /**
25
+ Matches any valid JSON value.
26
+
27
+ @see `Jsonify` if you need to transform a type to one that is assignable to `JsonValue`.
28
+
29
+ @category JSON
30
+ */
31
+ export type JsonValue = JsonPrimitive | JsonObject | JsonArray;
32
+
33
+ export {};
@@ -0,0 +1,37 @@
1
+ import type {JsonPrimitive} from './json-value.d.ts';
2
+
3
+ type JsonifiableObject = {[Key in string]?: Jsonifiable} | {toJSON: () => Jsonifiable};
4
+ type JsonifiableArray = readonly Jsonifiable[];
5
+
6
+ /**
7
+ Matches a value that can be losslessly converted to JSON.
8
+
9
+ Can be used to type values that you expect to pass to `JSON.stringify`.
10
+
11
+ `undefined` is allowed in object fields (for example, `{a?: number}`) as a special case even though `JSON.stringify({a: undefined})` is `{}` because it makes this class more widely useful and checking for undefined-but-present values is likely an anti-pattern.
12
+
13
+ @example
14
+ ```
15
+ import type {Jsonifiable} from 'type-fest';
16
+
17
+ // @ts-expect-error
18
+ const error: Jsonifiable = {
19
+ map: new Map([['a', 1]]),
20
+ };
21
+
22
+ console.log(JSON.stringify(error)); // {"map": {}}
23
+
24
+ const good: Jsonifiable = {
25
+ number: 3,
26
+ date: new Date('2025-12-25'),
27
+ missing: undefined,
28
+ };
29
+
30
+ console.log(JSON.stringify(good)); // {"number": 3, "date": "2025-12-25T00:00:00.000Z"}
31
+ ```
32
+
33
+ @category JSON
34
+ */
35
+ export type Jsonifiable = JsonPrimitive | JsonifiableObject | JsonifiableArray;
36
+
37
+ export {};
@@ -0,0 +1,127 @@
1
+ import type {JsonPrimitive, JsonValue} from './json-value.d.ts';
2
+ import type {EmptyObject} from './empty-object.d.ts';
3
+ import type {UndefinedToOptional} from './internal/index.d.ts';
4
+ import type {IsAny} from './is-any.d.ts';
5
+ import type {IsNever} from './is-never.d.ts';
6
+ import type {IsUnknown} from './is-unknown.d.ts';
7
+ import type {NegativeInfinity, PositiveInfinity} from './numeric.d.ts';
8
+ import type {TypedArray} from './typed-array.d.ts';
9
+ import type {UnknownArray} from './unknown-array.d.ts';
10
+
11
+ // Note: The return value has to be `any` and not `unknown` so it can match `void`.
12
+ type NotJsonable = ((...arguments_: any[]) => any) | undefined | symbol;
13
+
14
+ type NeverToNull<T> = IsNever<T> extends true ? null : T;
15
+ type UndefinedToNull<T> = T extends undefined ? null : T;
16
+
17
+ // Handles tuples and arrays
18
+ type JsonifyList<T extends UnknownArray> = T extends readonly []
19
+ ? []
20
+ : T extends readonly [infer F, ...infer R]
21
+ ? [F, ...R] extends T // With TS 5.8.3, if `string[] & ['foo']`, `R` is `unknown[]` here, making the inferred types not equal to the original one
22
+ ? [NeverToNull<Jsonify<F>>, ...JsonifyList<R>]
23
+ : [NeverToNull<Jsonify<F>>]
24
+ : IsUnknown<T[number]> extends true
25
+ ? JsonValue[]
26
+ : Array<T[number] extends NotJsonable ? null : Jsonify<UndefinedToNull<T[number]>>>;
27
+
28
+ type FilterJsonableKeys<T extends object> = {
29
+ [Key in keyof T]: T[Key] extends NotJsonable ? never : Key;
30
+ }[keyof T];
31
+
32
+ /**
33
+ JSON serialize objects (not including arrays) and classes.
34
+ */
35
+ type JsonifyObject<T extends object> = {
36
+ [Key in keyof Pick<T, FilterJsonableKeys<T>>]: Jsonify<T[Key]>;
37
+ };
38
+
39
+ /**
40
+ Transform a type to one that is assignable to the `JsonValue` type.
41
+
42
+ This includes:
43
+ 1. Transforming JSON `interface` to a `type` that is assignable to `JsonValue`.
44
+ 2. Transforming non-JSON value that is *jsonable* to a type that is assignable to `JsonValue`, where *jsonable* means the non-JSON value implements the `.toJSON()` method that returns a value that is assignable to `JsonValue`.
45
+
46
+ @remarks
47
+
48
+ An interface cannot be structurally compared to `JsonValue` because an interface can be re-opened to add properties that may not satisfy `JsonValue`.
49
+
50
+ @example
51
+ ```
52
+ import type {Jsonify, JsonValue} from 'type-fest';
53
+
54
+ interface Geometry {
55
+ type: 'Point' | 'Polygon';
56
+ coordinates: [number, number];
57
+ }
58
+
59
+ const point: Geometry = {
60
+ type: 'Point',
61
+ coordinates: [1, 1],
62
+ };
63
+
64
+ declare function problemFn(data: JsonValue): void;
65
+
66
+ // @ts-expect-error
67
+ problemFn(point); // Error: type Geometry is not assignable to parameter of type JsonValue because it is an interface
68
+
69
+ declare function fixedFn<T>(data: Jsonify<T>): void;
70
+
71
+ fixedFn(point); // Good: point is assignable. Jsonify<T> transforms Geometry into value assignable to JsonValue
72
+
73
+ // @ts-expect-error
74
+ fixedFn(new Date()); // Error: As expected, Date is not assignable. Jsonify<T> cannot transform Date into a value assignable to JsonValue
75
+ ```
76
+
77
+ Non-JSON values such as `Date` implement `.toJSON()`, so they can be transformed to a value assignable to `JsonValue`:
78
+
79
+ @example
80
+ ```
81
+ import type {Jsonify} from 'type-fest';
82
+
83
+ const time = {
84
+ timeValue: new Date(),
85
+ };
86
+
87
+ // `Jsonify<typeof time>` is equivalent to `{timeValue: string}`
88
+ const timeJson = JSON.parse(JSON.stringify(time)) as Jsonify<typeof time>;
89
+ ```
90
+
91
+ @link https://github.com/Microsoft/TypeScript/issues/1897#issuecomment-710744173
92
+
93
+ @category JSON
94
+ */
95
+ export type Jsonify<T> = IsAny<T> extends true
96
+ ? any
97
+ : T extends PositiveInfinity | NegativeInfinity
98
+ ? null
99
+ : T extends JsonPrimitive
100
+ ? T
101
+ : // Any object with toJSON is special case
102
+ T extends {toJSON(): infer J}
103
+ ? (() => J) extends () => JsonValue // Is J assignable to JsonValue?
104
+ ? J // Then T is Jsonable and its Jsonable value is J
105
+ : Jsonify<J> // Maybe if we look a level deeper we'll find a JsonValue
106
+ : // Instanced primitives are objects
107
+ T extends Number
108
+ ? number
109
+ : T extends String
110
+ ? string
111
+ : T extends Boolean
112
+ ? boolean
113
+ : T extends Map<any, any> | Set<any>
114
+ ? EmptyObject
115
+ : T extends TypedArray
116
+ ? Record<string, number>
117
+ : T extends NotJsonable
118
+ ? never // Non-JSONable type union was found not empty
119
+ : T extends UnknownArray
120
+ ? JsonifyList<T>
121
+ : T extends object
122
+ ? JsonifyObject<UndefinedToOptional<T>> // JsonifyObject recursive call for its children
123
+ : IsUnknown<T> extends true
124
+ ? JsonValue
125
+ : never; // Otherwise any other non-object is removed
126
+
127
+ export {};
@@ -0,0 +1,46 @@
1
+ import type {_DefaultDelimiterCaseOptions, DelimiterCase} from './delimiter-case.d.ts';
2
+ import type {ApplyDefaultOptions} from './internal/index.d.ts';
3
+ import type {WordsOptions} from './words.d.ts';
4
+
5
+ /**
6
+ Convert a string literal to kebab-case.
7
+
8
+ This can be useful when, for example, converting a camel-cased object property to a kebab-cased CSS class name or a command-line flag.
9
+
10
+ @example
11
+ ```
12
+ import type {KebabCase} from 'type-fest';
13
+
14
+ // Simple
15
+
16
+ const someVariable: KebabCase<'fooBar'> = 'foo-bar';
17
+ const someVariableNoSplitOnNumbers: KebabCase<'p2pNetwork', {splitOnNumbers: false}> = 'p2p-network';
18
+
19
+ // Advanced
20
+
21
+ type KebabCasedProperties<T> = {
22
+ [K in keyof T as KebabCase<K>]: T[K]
23
+ };
24
+
25
+ type CliOptions = {
26
+ dryRun: boolean;
27
+ includeFile: string;
28
+ foo: number;
29
+ };
30
+
31
+ const rawCliOptions: KebabCasedProperties<CliOptions> = {
32
+ 'dry-run': true,
33
+ 'include-file': 'bar.js',
34
+ foo: 123,
35
+ };
36
+ ```
37
+
38
+ @category Change case
39
+ @category Template literal
40
+ */
41
+ export type KebabCase<
42
+ Value,
43
+ Options extends WordsOptions = {},
44
+ > = DelimiterCase<Value, '-', ApplyDefaultOptions<WordsOptions, _DefaultDelimiterCaseOptions, Options>>;
45
+
46
+ export {};