@depup/type-fest 5.4.4-depup.0 → 5.9.0-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 (130) hide show
  1. package/README.md +2 -2
  2. package/changes.json +5 -0
  3. package/index.d.ts +23 -8
  4. package/package.json +17 -11
  5. package/readme.md +98 -64
  6. package/source/absolute.d.ts +52 -0
  7. package/source/all-extend.d.ts +8 -7
  8. package/source/all-union-fields.d.ts +18 -18
  9. package/source/and-all.d.ts +76 -0
  10. package/source/and.d.ts +4 -3
  11. package/source/array-length.d.ts +36 -0
  12. package/source/array-reverse.d.ts +4 -3
  13. package/source/array-splice.d.ts +26 -26
  14. package/source/array-tail.d.ts +4 -4
  15. package/source/camel-case.d.ts +38 -5
  16. package/source/camel-cased-properties-deep.d.ts +11 -4
  17. package/source/camel-cased-properties.d.ts +5 -1
  18. package/source/conditional-keys.d.ts +1 -1
  19. package/source/conditional-pick-deep.d.ts +5 -3
  20. package/source/conditional-pick.d.ts +6 -4
  21. package/source/delimiter-case.d.ts +11 -9
  22. package/source/delimiter-cased-properties-deep.d.ts +8 -1
  23. package/source/delimiter-cased-properties.d.ts +5 -1
  24. package/source/empty-object.d.ts +1 -1
  25. package/source/entries.d.ts +1 -1
  26. package/source/entry.d.ts +1 -1
  27. package/source/exclude-exactly.d.ts +57 -0
  28. package/source/exclude-rest-element.d.ts +4 -4
  29. package/source/exclusify-union.d.ts +4 -4
  30. package/source/extends-strict.d.ts +129 -22
  31. package/source/extract-exactly.d.ts +56 -0
  32. package/source/get.d.ts +1 -1
  33. package/source/greater-than-or-equal.d.ts +34 -1
  34. package/source/greater-than.d.ts +37 -3
  35. package/source/has-optional-keys.d.ts +1 -1
  36. package/source/has-readonly-keys.d.ts +1 -1
  37. package/source/has-required-keys.d.ts +1 -1
  38. package/source/has-writable-keys.d.ts +1 -1
  39. package/source/int-closed-range.d.ts +1 -3
  40. package/source/int-range.d.ts +3 -5
  41. package/source/internal/array.d.ts +8 -15
  42. package/source/internal/keys.d.ts +9 -9
  43. package/source/internal/numeric.d.ts +19 -27
  44. package/source/internal/object.d.ts +44 -6
  45. package/source/internal/string.d.ts +1 -76
  46. package/source/internal/tuple.d.ts +3 -3
  47. package/source/internal/type.d.ts +16 -9
  48. package/source/is-boolean-literal.d.ts +39 -0
  49. package/source/is-equal.d.ts +0 -1
  50. package/source/is-integer.d.ts +8 -8
  51. package/source/is-literal.d.ts +43 -267
  52. package/source/is-numeric-literal.d.ts +50 -0
  53. package/source/is-string-literal.d.ts +72 -0
  54. package/source/is-symbol-literal.d.ts +39 -0
  55. package/source/is-union.d.ts +12 -12
  56. package/source/iterable-element.d.ts +5 -5
  57. package/source/jsonify.d.ts +5 -9
  58. package/source/kebab-case.d.ts +1 -0
  59. package/source/kebab-cased-properties-deep.d.ts +7 -0
  60. package/source/kebab-cased-properties.d.ts +5 -1
  61. package/source/keys-of-union.d.ts +2 -2
  62. package/source/last-array-element.d.ts +66 -13
  63. package/source/less-than-or-equal.d.ts +40 -4
  64. package/source/less-than.d.ts +35 -3
  65. package/source/literal-to-primitive.d.ts +1 -1
  66. package/source/literal-union.d.ts +1 -1
  67. package/source/merge-exclusive.d.ts +3 -3
  68. package/source/merge.d.ts +25 -0
  69. package/source/multidimensional-array.d.ts +1 -1
  70. package/source/multidimensional-readonly-array.d.ts +1 -1
  71. package/source/non-nullable-deep.d.ts +102 -0
  72. package/source/numeric.d.ts +3 -3
  73. package/source/object-merge.d.ts +21 -16
  74. package/source/omit-deep.d.ts +22 -23
  75. package/source/optional.d.ts +31 -0
  76. package/source/or-all.d.ts +73 -0
  77. package/source/or.d.ts +4 -11
  78. package/source/package-json.d.ts +7 -7
  79. package/source/partial-deep.d.ts +3 -1
  80. package/source/pascal-case.d.ts +1 -0
  81. package/source/pascal-cased-properties-deep.d.ts +7 -0
  82. package/source/pascal-cased-properties.d.ts +5 -1
  83. package/source/pick-deep.d.ts +8 -21
  84. package/source/readonly-deep.d.ts +5 -3
  85. package/source/remove-prefix.d.ts +16 -34
  86. package/source/remove-suffix.d.ts +114 -0
  87. package/source/rename-keys.d.ts +163 -0
  88. package/source/replace.d.ts +2 -2
  89. package/source/require-all-or-none.d.ts +5 -5
  90. package/source/require-at-least-one.d.ts +9 -11
  91. package/source/require-exactly-one.d.ts +7 -7
  92. package/source/require-one-or-none.d.ts +5 -5
  93. package/source/required-deep.d.ts +3 -1
  94. package/source/schema.d.ts +16 -8
  95. package/source/screaming-snake-case.d.ts +1 -0
  96. package/source/set-non-nullable-deep.d.ts +8 -4
  97. package/source/set-non-nullable.d.ts +4 -11
  98. package/source/set-optional.d.ts +6 -10
  99. package/source/set-parameter-type.d.ts +2 -2
  100. package/source/set-readonly.d.ts +4 -8
  101. package/source/set-required-deep.d.ts +3 -2
  102. package/source/set-required.d.ts +4 -8
  103. package/source/shared-union-fields-deep.d.ts +5 -4
  104. package/source/shared-union-fields.d.ts +9 -9
  105. package/source/snake-case.d.ts +1 -0
  106. package/source/snake-cased-properties-deep.d.ts +7 -0
  107. package/source/snake-cased-properties.d.ts +5 -1
  108. package/source/some-extend.d.ts +115 -0
  109. package/source/split-on-rest-element.d.ts +6 -4
  110. package/source/split.d.ts +1 -1
  111. package/source/spread.d.ts +1 -5
  112. package/source/string-length.d.ts +38 -0
  113. package/source/string-repeat.d.ts +48 -21
  114. package/source/string-slice.d.ts +1 -1
  115. package/source/string-to-array.d.ts +97 -0
  116. package/source/string-to-number.d.ts +67 -0
  117. package/source/subtract.d.ts +4 -3
  118. package/source/sum.d.ts +5 -4
  119. package/source/tagged.d.ts +5 -7
  120. package/source/tsconfig-json.d.ts +40 -8
  121. package/source/tuple-of.d.ts +42 -8
  122. package/source/typed-array.d.ts +1 -0
  123. package/source/union-length.d.ts +27 -0
  124. package/source/union-member.d.ts +65 -0
  125. package/source/union-to-intersection.d.ts +1 -1
  126. package/source/union-to-tuple.d.ts +10 -19
  127. package/source/unwrap-required.d.ts +37 -0
  128. package/source/words.d.ts +30 -4
  129. package/source/writable.d.ts +15 -19
  130. package/source/xor.d.ts +1 -1
@@ -6,7 +6,7 @@ import type {Simplify} from './simplify.d.ts';
6
6
  import type {UnknownArray} from './unknown-array.d.ts';
7
7
 
8
8
  /**
9
- Create a type that makes the given keys required. The remaining keys are kept as is. The sister of the `SetOptional` type.
9
+ Create a type that makes the given keys required, while keeping the remaining keys as is.
10
10
 
11
11
  Use-case: You want to define a single model where the only thing that changes is whether or not some of the keys are required.
12
12
 
@@ -21,11 +21,7 @@ type Foo = {
21
21
  };
22
22
 
23
23
  type SomeRequired = SetRequired<Foo, 'b' | 'c'>;
24
- // type SomeRequired = {
25
- // a?: number;
26
- // b: string; // Was already required and still is.
27
- // c: boolean; // Is now required.
28
- // }
24
+ //=> {a?: number; b: string; c: boolean}
29
25
 
30
26
  // Set specific indices in an array to be required.
31
27
  type ArrayExample = SetRequired<[number?, number?, number?], 0 | 1>;
@@ -47,9 +43,9 @@ type _SetRequired<BaseType, Keys extends keyof BaseType> =
47
43
  : never
48
44
  : Simplify<
49
45
  // Pick just the keys that are optional from the base type.
50
- Except<BaseType, Keys> &
46
+ Except<BaseType, Keys>
51
47
  // Pick the keys that should be required from the base type and make them required.
52
- Required<HomomorphicPick<BaseType, Keys>>
48
+ & Required<HomomorphicPick<BaseType, Keys>>
53
49
  >;
54
50
 
55
51
  /**
@@ -89,7 +89,7 @@ function displayPetInfoWithSharedUnionFieldsDeep(petInfo: SharedUnionFieldsDeep<
89
89
  export type SharedUnionFieldsDeep<Union, Options extends SharedUnionFieldsDeepOptions = {}> =
90
90
  ApplyDefaultOptions<SharedUnionFieldsDeepOptions, DefaultSharedUnionFieldsDeepOptions, Options> extends infer OptionsWithDefaults extends Required<SharedUnionFieldsDeepOptions>
91
91
  // `Union extends` will convert `Union`
92
- // to a [distributive conditionaltype](https://www.typescriptlang.org/docs/handbook/release-notes/typescript-2-8.html#distributive-conditional-types).
92
+ // to a [distributive conditional type](https://www.typescriptlang.org/docs/handbook/release-notes/typescript-2-8.html#distributive-conditional-types).
93
93
  // But this is not what we want, so we need to wrap `Union` with `[]` to prevent it.
94
94
  ? [Union] extends [NonRecursiveType | ReadonlyMap<unknown, unknown> | ReadonlySet<unknown>]
95
95
  ? Union
@@ -106,11 +106,12 @@ export type SharedUnionFieldsDeep<Union, Options extends SharedUnionFieldsDeepOp
106
106
  Same as `SharedUnionFieldsDeep`, but accepts only `object`s and as inputs. Internal helper for `SharedUnionFieldsDeep`.
107
107
  */
108
108
  type SharedObjectUnionFieldsDeep<Union, Options extends Required<SharedUnionFieldsDeepOptions>> =
109
- // `keyof Union` can extract the same key in union type, if there is no same key, return never.
110
- keyof Union extends infer Keys
109
+ // Extract the shared keys from the union. Throughout this type, use `Keys` instead of `keyof Union`
110
+ // to prevent the mapped type from distributing over the union.
111
+ keyof Union extends infer Keys extends keyof Union
111
112
  ? IsNever<Keys> extends false
112
113
  ? {
113
- [Key in keyof Union]:
114
+ [Key in Keys]:
114
115
  Union[Key] extends NonRecursiveType
115
116
  ? Union[Key]
116
117
  // Remove `undefined` from the union to support optional
@@ -66,14 +66,14 @@ function displayPetInfoWithSharedUnionFields(petInfo: SharedUnionFields<Cat | Do
66
66
  @category Union
67
67
  */
68
68
  export type SharedUnionFields<Union> =
69
- Extract<Union, NonRecursiveType | ReadonlyMap<unknown, unknown> | ReadonlySet<unknown> | UnknownArray> extends infer SkippedMembers
70
- ? Exclude<Union, SkippedMembers> extends infer RelevantMembers
71
- ?
72
- | SkippedMembers
73
- | (IsNever<RelevantMembers> extends true
74
- ? never
75
- : Simplify<Pick<RelevantMembers, keyof RelevantMembers>>)
76
- : never
77
- : never;
69
+ Extract<Union, NonRecursiveType | ReadonlyMap<unknown, unknown> | ReadonlySet<unknown> | UnknownArray> extends infer SkippedMembers
70
+ ? Exclude<Union, SkippedMembers> extends infer RelevantMembers
71
+ ? // eslint-disable-line @stylistic/operator-linebreak
72
+ | SkippedMembers
73
+ | (IsNever<RelevantMembers> extends true
74
+ ? never
75
+ : Simplify<Pick<RelevantMembers, keyof RelevantMembers>>)
76
+ : never
77
+ : never;
78
78
 
79
79
  export {};
@@ -16,6 +16,7 @@ import type {SnakeCase} from 'type-fest';
16
16
  const someVariable: SnakeCase<'fooBar'> = 'foo_bar';
17
17
  const noSplitOnNumbers: SnakeCase<'p2pNetwork'> = 'p2p_network';
18
18
  const splitOnNumbers: SnakeCase<'p2pNetwork', {splitOnNumbers: true}> = 'p_2_p_network';
19
+ const splitOnPunctuation: SnakeCase<'div.card::after', {splitOnPunctuation: true}> = 'div_card_after';
19
20
 
20
21
  // Advanced
21
22
 
@@ -51,6 +51,13 @@ const splitOnNumbers: SnakeCasedPropertiesDeep<{line1: {line2: [{line3: string}]
51
51
  ],
52
52
  },
53
53
  };
54
+
55
+ const splitOnPunctuation: SnakeCasedPropertiesDeep<{'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 snake case but not recursively.
7
+ Convert top-level object properties to snake 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: SnakeCasedProperties<User> = {
28
28
  const splitOnNumbers: SnakeCasedProperties<{line1: string}, {splitOnNumbers: true}> = {
29
29
  'line_1': 'string',
30
30
  };
31
+
32
+ const splitOnPunctuation: SnakeCasedProperties<{'foo::bar': string}, {splitOnPunctuation: true}> = {
33
+ 'foo_bar': 'string',
34
+ };
31
35
  ```
32
36
 
33
37
  @category Change case
@@ -0,0 +1,115 @@
1
+ import type {CollapseRestElement} from './internal/array.d.ts';
2
+ import type {ApplyDefaultOptions} from './internal/object.d.ts';
3
+ import type {IfNotAnyOrNever, Not} from './internal/type.d.ts';
4
+ import type {IsAny} from './is-any.d.ts';
5
+ import type {IsNever} from './is-never.d.ts';
6
+ import type {Or} from './or.d.ts';
7
+ import type {UnknownArray} from './unknown-array.d.ts';
8
+
9
+ /**
10
+ @see {@link SomeExtend}
11
+ */
12
+ export type SomeExtendOptions = {
13
+ /**
14
+ Consider `never` elements to match the target type only if the target type itself is `never` (or `any`).
15
+
16
+ - When set to `true` (default), `never` is _not_ treated as a bottom type, instead, it is treated as a type that matches only itself (or `any`).
17
+ - When set to `false`, `never` is treated as a bottom type, and behaves as it normally would.
18
+
19
+ @default true
20
+
21
+ @example
22
+ ```
23
+ import type {SomeExtend} from 'type-fest';
24
+
25
+ type A = SomeExtend<[1, 2, never], string, {strictNever: true}>;
26
+ //=> false
27
+
28
+ type B = SomeExtend<[1, 2, never], string, {strictNever: false}>;
29
+ //=> true
30
+
31
+ type C = SomeExtend<[1, never], never, {strictNever: true}>;
32
+ //=> true
33
+
34
+ type D = SomeExtend<[1, never], never, {strictNever: false}>;
35
+ //=> true
36
+
37
+ type E = SomeExtend<[never], any, {strictNever: true}>;
38
+ //=> true
39
+
40
+ type F = SomeExtend<[never], any, {strictNever: false}>;
41
+ //=> true
42
+ ```
43
+ */
44
+ strictNever?: boolean;
45
+ };
46
+
47
+ type DefaultSomeExtendOptions = {
48
+ strictNever: true;
49
+ };
50
+
51
+ /**
52
+ Returns a boolean for whether some element in an array type extends another type.
53
+
54
+ @example
55
+ ```
56
+ import type {SomeExtend} from 'type-fest';
57
+
58
+ type A = SomeExtend<['1', '2', 3], number>;
59
+ //=> true
60
+
61
+ type B = SomeExtend<[1, 2, 3], string>;
62
+ //=> false
63
+
64
+ type C = SomeExtend<[string, number | string], number>;
65
+ //=> boolean
66
+
67
+ type D = SomeExtend<[true, boolean, true], false>;
68
+ //=> boolean
69
+ ```
70
+
71
+ Note: Behaviour of optional elements depend on the `exactOptionalPropertyTypes` compiler option. When the option is disabled, the target type must include `undefined` for a successful match.
72
+
73
+ ```
74
+ // @exactOptionalPropertyTypes: true
75
+ import type {SomeExtend} from 'type-fest';
76
+
77
+ type A = SomeExtend<[1?, 2?, '3'?], string>;
78
+ //=> true
79
+ ```
80
+
81
+ ```
82
+ // @exactOptionalPropertyTypes: false
83
+ import type {SomeExtend} from 'type-fest';
84
+
85
+ type A = SomeExtend<[1?, 2?, '3'?], string>;
86
+ //=> boolean
87
+
88
+ type B = SomeExtend<[1?, 2?, '3'?], string | undefined>;
89
+ //=> true
90
+ ```
91
+
92
+ @see {@link SomeExtendOptions}
93
+
94
+ @category Utilities
95
+ @category Array
96
+ */
97
+ export type SomeExtend<TArray extends UnknownArray, Type, Options extends SomeExtendOptions = {}> =
98
+ _SomeExtend<CollapseRestElement<TArray>, Type, ApplyDefaultOptions<SomeExtendOptions, DefaultSomeExtendOptions, Options>>;
99
+
100
+ type _SomeExtend<TArray extends UnknownArray, Type, Options extends Required<SomeExtendOptions>> = IfNotAnyOrNever<TArray, {
101
+ ifNot: TArray extends readonly [infer First, ...infer Rest]
102
+ ? IsNever<First> extends true
103
+ ? Or<Or<IsNever<Type>, IsAny<Type>>, Not<Options['strictNever']>> extends true
104
+ // If target `Type` is also `never`, or is `any`, or `strictNever` is disabled, return `true`.
105
+ ? true
106
+ : _SomeExtend<Rest, Type, Options>
107
+ : First extends Type
108
+ ? true
109
+ : _SomeExtend<Rest, Type, Options>
110
+ : false;
111
+ ifAny: false;
112
+ ifNever: false;
113
+ }>;
114
+
115
+ export {};
@@ -65,10 +65,12 @@ export type SplitOnRestElement<
65
65
  Options extends SplitOnRestElementOptions = {},
66
66
  > =
67
67
  Array_ extends unknown // For distributing `Array_`
68
- ? IfNotAnyOrNever<Array_, _SplitOnRestElement<
69
- Array_,
70
- ApplyDefaultOptions<SplitOnRestElementOptions, DefaultSplitOnRestElementOptions, Options>
71
- >> extends infer Result extends UnknownArray
68
+ ? IfNotAnyOrNever<Array_, {
69
+ ifNot: _SplitOnRestElement<
70
+ Array_,
71
+ ApplyDefaultOptions<SplitOnRestElementOptions, DefaultSplitOnRestElementOptions, Options>
72
+ >;
73
+ }> extends infer Result extends UnknownArray
72
74
  ? If<IsArrayReadonly<Array_>, Readonly<Result>, Result>
73
75
  : never // Should never happen
74
76
  : never; // Should never happen
package/source/split.d.ts CHANGED
@@ -1,6 +1,6 @@
1
1
  import type {And} from './and.d.ts';
2
2
  import type {ApplyDefaultOptions, Not} from './internal/index.d.ts';
3
- import type {IsStringLiteral} from './is-literal.d.ts';
3
+ import type {IsStringLiteral} from './is-string-literal.d.ts';
4
4
  import type {Or} from './or.d.ts';
5
5
 
6
6
  /**
@@ -41,11 +41,7 @@ const bar = {c: false};
41
41
  const fooBar = {...foo, ...bar};
42
42
 
43
43
  type FooBar = Spread<Foo, Bar>;
44
- // type FooBar = {
45
- // a: number;
46
- // b?: string | number | undefined;
47
- // c: boolean;
48
- // }
44
+ //=> {a: number; b?: string | number; c: boolean}
49
45
 
50
46
  declare function baz(argument: FooBar): void;
51
47
 
@@ -0,0 +1,38 @@
1
+ import type {StringToArray} from './string-to-array.d.ts';
2
+
3
+ /**
4
+ Returns the length of the given string.
5
+
6
+ @example
7
+ ```
8
+ import type {StringLength} from 'type-fest';
9
+
10
+ type A = StringLength<'abcde'>;
11
+ //=> 5
12
+
13
+ type B = StringLength<'abcde' | 'fgh'>;
14
+ //=> 3 | 5
15
+ ```
16
+
17
+ For non-literal strings, the result is `number` because the length of a non-literal string can be any number.
18
+
19
+ @example
20
+ ```
21
+ import type {StringLength} from 'type-fest';
22
+
23
+ type A = StringLength<string>;
24
+ //=> number
25
+
26
+ type B = StringLength<Uppercase<string>>;
27
+ //=> number
28
+
29
+ type C = StringLength<`${string}abc`>;
30
+ //=> number
31
+ ```
32
+
33
+ @category String
34
+ @category Template literal
35
+ */
36
+ export type StringLength<S extends string> = StringToArray<S>['length'];
37
+
38
+ export {};
@@ -1,5 +1,6 @@
1
- import type {IsNumericLiteral} from './is-literal.d.ts';
1
+ import type {IsNumericLiteral} from './is-numeric-literal.d.ts';
2
2
  import type {IsNegative} from './numeric.d.ts';
3
+ import type {DigitCharacter} from './characters.d.ts';
3
4
 
4
5
  /**
5
6
  Returns a new string which contains the specified number of copies of a given string, just like `String#repeat()`.
@@ -9,9 +10,9 @@ Returns a new string which contains the specified number of copies of a given st
9
10
  import type {StringRepeat} from 'type-fest';
10
11
 
11
12
  declare function stringRepeat<
12
- Input extends string,
13
+ S extends string,
13
14
  Count extends number,
14
- >(input: Input, count: Count): StringRepeat<Input, Count>;
15
+ >(input: S, count: Count): StringRepeat<S, Count>;
15
16
 
16
17
  // The return type is the exact string literal, not just `string`.
17
18
 
@@ -22,28 +23,54 @@ stringRepeat('=', 3);
22
23
  //=> '==='
23
24
  ```
24
25
 
26
+ Note: If the specified count has a decimal part, the decimal part will be ignored.
27
+
28
+ @example
29
+ ```
30
+ import type {StringRepeat} from 'type-fest';
31
+
32
+ type DecimalCount = StringRepeat<'foo', 2.5>;
33
+ //=> 'foofoo'
34
+ ```
35
+
25
36
  @category String
26
37
  @category Template literal
27
38
  */
28
- export type StringRepeat<
29
- Input extends string,
30
- Count extends number,
31
- > = StringRepeatHelper<Input, Count>;
32
-
33
- type StringRepeatHelper<
34
- Input extends string,
35
- Count extends number,
36
- Counter extends never[] = [],
37
- Accumulator extends string = '',
38
- > =
39
- IsNegative<Count> extends true
40
- ? never
41
- : Input extends ''
42
- ? ''
43
- : Count extends Counter['length']
44
- ? Accumulator
39
+ export type StringRepeat<S extends string, Count extends number> =
40
+ Count extends unknown // To distribute `Count`
41
+ ? IsNegative<Count> extends true
42
+ ? never
43
+ : S extends ''
44
+ ? ''
45
45
  : IsNumericLiteral<Count> extends false
46
46
  ? string
47
- : StringRepeatHelper<Input, Count, [...Counter, never], `${Accumulator}${Input}`>;
47
+ : `${Count}` extends `${string}e${string}`
48
+ ? string
49
+ : BuildStringDigitByDigit<S, `${Count}`>
50
+ : never;
51
+
52
+ type BuildStringDigitByDigit<S extends string, Count extends string, Accumulator extends string = ''> =
53
+ Count extends `${infer First extends DigitCharacter}${infer Rest}`
54
+ ? BuildStringDigitByDigit<
55
+ S,
56
+ Rest,
57
+ `${RepeatStringTenTimes<Accumulator>}${DigitStringRepeat<S, First>}`
58
+ >
59
+ : Accumulator;
60
+
61
+ type RepeatStringTenTimes<S extends string> = `${S}${S}${S}${S}${S}${S}${S}${S}${S}${S}`;
62
+
63
+ type DigitStringRepeat<S extends string, Digit extends DigitCharacter> = [
64
+ '',
65
+ `${S}`,
66
+ `${S}${S}`,
67
+ `${S}${S}${S}`,
68
+ `${S}${S}${S}${S}`,
69
+ `${S}${S}${S}${S}${S}`,
70
+ `${S}${S}${S}${S}${S}${S}`,
71
+ `${S}${S}${S}${S}${S}${S}${S}`,
72
+ `${S}${S}${S}${S}${S}${S}${S}${S}`,
73
+ `${S}${S}${S}${S}${S}${S}${S}${S}${S}`,
74
+ ][Digit];
48
75
 
49
76
  export {};
@@ -1,6 +1,6 @@
1
1
  import type {Join} from './join.d.ts';
2
2
  import type {ArraySlice} from './array-slice.d.ts';
3
- import type {StringToArray} from './internal/index.d.ts';
3
+ import type {StringToArray} from './string-to-array.d.ts';
4
4
 
5
5
  /**
6
6
  Returns a string slice of a given range, just like `String#slice()`.
@@ -0,0 +1,97 @@
1
+ import type {ApplyDefaultOptions} from './internal/object.d.ts';
2
+ import type {IfNotAnyOrNever} from './internal/type.d.ts';
3
+ import type {IsStringLiteral} from './is-string-literal.d.ts';
4
+ import type {Or} from './or.d.ts';
5
+
6
+ /**
7
+ @see {@link StringToArray}
8
+ */
9
+ export type StringToArrayOptions = {
10
+ /**
11
+ When enabled, non-literal parts of the string (e.g., `string`, `Uppercase<string>`) are mapped as single elements instead of being mapped as a rest element.
12
+
13
+ Note: Enabling this option can produce misleading results that might not reflect the actual runtime behavior.
14
+ For example, `StringToArray<string, {mapNonLiteralsDirectly: true}>` returns `[string]`, but at runtime, the string could be `'abc'` (which satisfies `string`), and converting it to an array would result in `['a', 'b', 'c']`, which doesn't satisfy `[string]`.
15
+
16
+ So, it is recommended to not enable this option unless you are aware of the implications.
17
+
18
+ @default false
19
+
20
+ @example
21
+ ```
22
+ import type {StringToArray} from 'type-fest';
23
+
24
+ type A = StringToArray<string, {mapNonLiteralsDirectly: false}>;
25
+ //=> string[]
26
+
27
+ type B = StringToArray<string, {mapNonLiteralsDirectly: true}>;
28
+ //=> [string]
29
+
30
+ type C = StringToArray<`on${string}`, {mapNonLiteralsDirectly: false}>;
31
+ //=> ['o', 'n', ...string[]]
32
+
33
+ type D = StringToArray<`on${string}`, {mapNonLiteralsDirectly: true}>;
34
+ //=> ['o', 'n', string]
35
+
36
+ type E = StringToArray<`${string}xyz`, {mapNonLiteralsDirectly: false}>;
37
+ //=> [...string[], 'x', 'y', 'z']
38
+
39
+ type F = StringToArray<`${string}xyz`, {mapNonLiteralsDirectly: true}>;
40
+ //=> [string, 'x', 'y', 'z']
41
+ ```
42
+ */
43
+ mapNonLiteralsDirectly?: boolean;
44
+ };
45
+
46
+ type DefaultStringToArrayOptions = {
47
+ mapNonLiteralsDirectly: false;
48
+ };
49
+
50
+ /**
51
+ Returns an array of the characters of the specified string.
52
+
53
+ @example
54
+ ```
55
+ import type {StringToArray} from 'type-fest';
56
+
57
+ type A = StringToArray<'abcde'>;
58
+ //=> ['a', 'b', 'c', 'd', 'e']
59
+
60
+ type B = StringToArray<''>;
61
+ //=> []
62
+
63
+ type C = StringToArray<string>;
64
+ //=> string[]
65
+
66
+ type D = StringToArray<`foo${string}bar`>;
67
+ //=> ['f', 'o', 'o', ...string[], 'b', 'a', 'r']
68
+
69
+ type E = StringToArray<`foo${string}bar`, {mapNonLiteralsDirectly: true}>;
70
+ //=> ['f', 'o', 'o', string, 'b', 'a', 'r']
71
+ ```
72
+
73
+ @see {@link StringToArrayOptions}
74
+
75
+ @category String
76
+ */
77
+ export type StringToArray<S extends string, Options extends StringToArrayOptions = {}> =
78
+ IfNotAnyOrNever<
79
+ S,
80
+ {
81
+ ifNot: _StringToArray<S, ApplyDefaultOptions<StringToArrayOptions, DefaultStringToArrayOptions, Options>>;
82
+ ifAny: unknown[];
83
+ }
84
+ >;
85
+
86
+ type _StringToArray<S extends string, Options extends Required<StringToArrayOptions>, Accumulator extends string[] = []> =
87
+ S extends `${infer First}${infer Rest}`
88
+ ? Or<IsStringLiteral<First>, Options['mapNonLiteralsDirectly']> extends true
89
+ ? _StringToArray<Rest, Options, [...Accumulator, First]>
90
+ : _StringToArray<Rest, Options, [...Accumulator, ...First[]]>
91
+ : S extends ''
92
+ ? Accumulator
93
+ : Options['mapNonLiteralsDirectly'] extends true
94
+ ? [...Accumulator, S]
95
+ : [...Accumulator, ...S[]];
96
+
97
+ export {};
@@ -0,0 +1,67 @@
1
+ import type {IfNotAnyOrNever} from './internal/type.d.ts';
2
+ import type {NegativeInfinity, PositiveInfinity} from './numeric.d.ts';
3
+
4
+ /**
5
+ Converts a numeric string to a number.
6
+
7
+ @example
8
+ ```
9
+ import type {StringToNumber} from 'type-fest';
10
+
11
+ type PositiveInteger = StringToNumber<'1234'>;
12
+ //=> 1234
13
+
14
+ type NegativeInteger = StringToNumber<'-1234'>;
15
+ //=> -1234
16
+
17
+ type PositiveFloat = StringToNumber<'1234.56'>;
18
+ //=> 1234.56
19
+
20
+ type NegativeFloat = StringToNumber<'-1234.56'>;
21
+ //=> -1234.56
22
+
23
+ type PositiveInfinity = StringToNumber<'Infinity'>;
24
+ //=> Infinity
25
+
26
+ type NegativeInfinity = StringToNumber<'-Infinity'>;
27
+ //=> -Infinity
28
+ ```
29
+
30
+ Note: Some strings, such as `'1.50'`, `'0b10'`, or `'12_345'`, may look like they can be converted to numbers, but they don't actually have corresponding numeric literals. So, in such cases, this type produces `never`. See [type-fest#1446](https://github.com/sindresorhus/type-fest/pull/1446) for more details.
31
+
32
+ @example
33
+ ```
34
+ import type {StringToNumber} from 'type-fest';
35
+
36
+ type FractionalsEndingInZero = StringToNumber<'1.50'>;
37
+ //=> never
38
+
39
+ type NonDecimalBases = StringToNumber<'0b10' | '0o10' | '0x10'>;
40
+ //=> never
41
+
42
+ type NumericSeparators = StringToNumber<'12_345'>;
43
+ //=> never
44
+ ```
45
+
46
+ @category String
47
+ @category Numeric
48
+ @category Template literal
49
+ */
50
+ export type StringToNumber<S extends string> = IfNotAnyOrNever<S, {ifNot: _StringToNumber<S>; ifAny: number}>;
51
+
52
+ type _StringToNumber<S extends string> =
53
+ S extends `${infer N extends number}`
54
+ ? number extends N
55
+ ? `${number}` extends S
56
+ ? N
57
+ : never
58
+ : N
59
+ : string extends S
60
+ ? number
61
+ : S extends 'Infinity'
62
+ ? PositiveInfinity
63
+ : S extends '-Infinity'
64
+ ? NegativeInfinity
65
+ : never;
66
+
67
+ export {};
@@ -1,7 +1,8 @@
1
- import type {NumberAbsolute, ReverseSign} from './internal/index.d.ts';
1
+ import type {ReverseSign} from './internal/index.d.ts';
2
2
  import type {PositiveInfinity, NegativeInfinity, IsNegative} from './numeric.d.ts';
3
3
  import type {LessThan} from './less-than.d.ts';
4
4
  import type {TupleOf} from './tuple-of.d.ts';
5
+ import type {Absolute} from './absolute.d.ts';
5
6
 
6
7
  /**
7
8
  Returns the difference between two numbers.
@@ -59,9 +60,9 @@ type SubtractPostChecks<A extends number, B extends number, AreNegative = [IsNeg
59
60
  ? SubtractPositives<A, B>
60
61
  : AreNegative extends [true, true]
61
62
  // When both numbers are negative we subtract the absolute values and then reverse the sign
62
- ? ReverseSign<SubtractPositives<NumberAbsolute<A>, NumberAbsolute<B>>>
63
+ ? ReverseSign<SubtractPositives<Absolute<A>, Absolute<B>>>
63
64
  // When the signs are different we can add the absolute values and then reverse the sign if A < B
64
- : [...TupleOf<NumberAbsolute<A>>, ...TupleOf<NumberAbsolute<B>>] extends infer R extends unknown[]
65
+ : [...TupleOf<Absolute<A>>, ...TupleOf<Absolute<B>>] extends infer R extends unknown[]
65
66
  ? LessThan<A, B> extends true ? ReverseSign<R['length']> : R['length']
66
67
  : never;
67
68
 
package/source/sum.d.ts CHANGED
@@ -1,7 +1,8 @@
1
1
  import type {TupleOf} from './tuple-of.d.ts';
2
- import type {NumberAbsolute, TupleMax, ReverseSign} from './internal/index.d.ts';
2
+ import type {TupleMax, ReverseSign} from './internal/index.d.ts';
3
3
  import type {PositiveInfinity, NegativeInfinity, IsNegative} from './numeric.d.ts';
4
4
  import type {Subtract} from './subtract.d.ts';
5
+ import type {Absolute} from './absolute.d.ts';
5
6
 
6
7
  /**
7
8
  Returns the sum of two numbers.
@@ -57,11 +58,11 @@ type SumPostChecks<A extends number, B extends number, AreNegative = [IsNegative
57
58
  ? SumPositives<A, B>
58
59
  : AreNegative extends [true, true]
59
60
  // When both numbers are negative we add the absolute values and then reverse the sign
60
- ? ReverseSign<SumPositives<NumberAbsolute<A>, NumberAbsolute<B>>>
61
+ ? ReverseSign<SumPositives<Absolute<A>, Absolute<B>>>
61
62
  // When the signs are different we can subtract the absolute values, remove the sign
62
63
  // and then reverse the sign if the larger absolute value is negative
63
- : NumberAbsolute<Subtract<NumberAbsolute<A>, NumberAbsolute<B>>> extends infer Result extends number
64
- ? TupleMax<[NumberAbsolute<A>, NumberAbsolute<B>]> extends infer Max_ extends number
64
+ : Absolute<Subtract<Absolute<A>, Absolute<B>>> extends infer Result extends number
65
+ ? TupleMax<[Absolute<A>, Absolute<B>]> extends infer Max_ extends number
65
66
  ? Max_ extends A | B
66
67
  // The larger absolute value is positive, so the result is positive
67
68
  ? Result