type-fest 5.1.0 → 5.2.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 (47) hide show
  1. package/index.d.ts +4 -0
  2. package/package.json +3 -1
  3. package/readme.md +3 -1
  4. package/source/all-union-fields.d.ts +1 -1
  5. package/source/and.d.ts +2 -0
  6. package/source/array-element.d.ts +46 -0
  7. package/source/arrayable.d.ts +1 -1
  8. package/source/camel-case.d.ts +4 -3
  9. package/source/camel-cased-properties-deep.d.ts +2 -2
  10. package/source/camel-cased-properties.d.ts +2 -2
  11. package/source/conditional-pick-deep.d.ts +2 -2
  12. package/source/conditional-simplify-deep.d.ts +1 -1
  13. package/source/conditional-simplify.d.ts +1 -1
  14. package/source/delimiter-case.d.ts +2 -2
  15. package/source/delimiter-cased-properties-deep.d.ts +2 -2
  16. package/source/delimiter-cased-properties.d.ts +2 -2
  17. package/source/empty-object.d.ts +1 -1
  18. package/source/exact.d.ts +2 -1
  19. package/source/exclude-rest-element.d.ts +7 -4
  20. package/source/exclusify-union.d.ts +113 -0
  21. package/source/extract-rest-element.d.ts +2 -1
  22. package/source/extract-strict.d.ts +1 -1
  23. package/source/greater-than-or-equal.d.ts +7 -1
  24. package/source/if.d.ts +35 -0
  25. package/source/int-closed-range.d.ts +1 -1
  26. package/source/int-range.d.ts +1 -1
  27. package/source/internal/array.d.ts +0 -9
  28. package/source/internal/type.d.ts +32 -0
  29. package/source/kebab-cased-properties-deep.d.ts +2 -2
  30. package/source/kebab-cased-properties.d.ts +2 -2
  31. package/source/literal-to-primitive-deep.d.ts +1 -1
  32. package/source/numeric.d.ts +16 -16
  33. package/source/omit-index-signature.d.ts +1 -1
  34. package/source/or.d.ts +7 -5
  35. package/source/package-json.d.ts +20 -0
  36. package/source/partial-on-undefined-deep.d.ts +1 -1
  37. package/source/pascal-cased-properties-deep.d.ts +2 -2
  38. package/source/pascal-cased-properties.d.ts +2 -2
  39. package/source/pick-index-signature.d.ts +1 -1
  40. package/source/shared-union-fields-deep.d.ts +1 -1
  41. package/source/shared-union-fields.d.ts +2 -2
  42. package/source/simplify-deep.d.ts +1 -1
  43. package/source/simplify.d.ts +1 -1
  44. package/source/snake-cased-properties-deep.d.ts +2 -2
  45. package/source/snake-cased-properties.d.ts +2 -2
  46. package/source/split-on-rest-element.d.ts +2 -2
  47. package/source/writable-deep.d.ts +1 -1
package/index.d.ts CHANGED
@@ -141,6 +141,7 @@ export type {ArrayValues} from './source/array-values.d.ts';
141
141
  export type {ArraySlice} from './source/array-slice.d.ts';
142
142
  export type {ArraySplice} from './source/array-splice.d.ts';
143
143
  export type {ArrayTail} from './source/array-tail.d.ts';
144
+ export type {ArrayElement} from './source/array-element.d.ts';
144
145
  export type {SetFieldType, SetFieldTypeOptions} from './source/set-field-type.d.ts';
145
146
  export type {Paths, PathsOptions} from './source/paths.d.ts';
146
147
  export type {AllUnionFields} from './source/all-union-fields.d.ts';
@@ -162,6 +163,7 @@ export type {IsUppercase} from './source/is-uppercase.d.ts';
162
163
  export type {IsOptional} from './source/is-optional.d.ts';
163
164
  export type {IsNullable} from './source/is-nullable.d.ts';
164
165
  export type {TupleOf} from './source/tuple-of.d.ts';
166
+ export type {ExclusifyUnion} from './source/exclusify-union.d.ts';
165
167
 
166
168
  // Template literal types
167
169
  export type {CamelCase, CamelCaseOptions} from './source/camel-case.d.ts';
@@ -202,3 +204,5 @@ export type {TsConfigJson} from './source/tsconfig-json.d.ts';
202
204
  export type {ExtendsStrict} from './source/extends-strict.d.ts';
203
205
  export type {ExtractStrict} from './source/extract-strict.d.ts';
204
206
  export type {ExcludeStrict} from './source/exclude-strict.d.ts';
207
+
208
+ export {};
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "type-fest",
3
- "version": "5.1.0",
3
+ "version": "5.2.0",
4
4
  "description": "A collection of essential TypeScript types",
5
5
  "license": "(MIT OR CC0-1.0)",
6
6
  "repository": "sindresorhus/type-fest",
@@ -54,6 +54,8 @@
54
54
  },
55
55
  "devDependencies": {
56
56
  "@sindresorhus/tsconfig": "^8.0.1",
57
+ "@typescript-eslint/parser": "^8.44.0",
58
+ "eslint": "^9.35.0",
57
59
  "expect-type": "^1.2.2",
58
60
  "npm-run-all2": "^8.0.4",
59
61
  "tsd": "^0.33.0",
package/readme.md CHANGED
@@ -179,7 +179,7 @@ Click the type names for complete docs.
179
179
  - [`DistributedOmit`](source/distributed-omit.d.ts) - Omits keys from a type, distributing the operation over a union.
180
180
  - [`DistributedPick`](source/distributed-pick.d.ts) - Picks keys from a type, distributing the operation over a union.
181
181
  - [`And`](source/and.d.ts) - Returns a boolean for whether two given types are both true.
182
- - [`Or`](source/or.d.ts) - Returns a boolean for whether either of two given types are true.
182
+ - [`Or`](source/or.d.ts) - Returns a boolean for whether either of two given types is true.
183
183
  - [`Xor`](source/xor.d.ts) - Returns a boolean for whether only one of two given types is true.
184
184
  - [`AllExtend`](source/all-extend.d.ts) - Returns a boolean for whether every element in an array type extends another type.
185
185
  - [`NonEmptyTuple`](source/non-empty-tuple.d.ts) - Matches any non-empty tuple.
@@ -188,6 +188,7 @@ Click the type names for complete docs.
188
188
  - [`FindGlobalInstanceType`](source/find-global-type.d.ts) - Tries to find one or more types from their globally-defined constructors.
189
189
  - [`ConditionalSimplify`](source/conditional-simplify.d.ts) - Simplifies a type while including and/or excluding certain types from being simplified.
190
190
  - [`ConditionalSimplifyDeep`](source/conditional-simplify-deep.d.ts) - Recursively simplifies a type while including and/or excluding certain types from being simplified.
191
+ - [`ExclusifyUnion`](source/exclusify-union.d.ts) - Ensure mutual exclusivity in object unions by adding other members’ keys as `?: never`.
191
192
 
192
193
  ### Type Guard
193
194
 
@@ -249,6 +250,7 @@ Click the type names for complete docs.
249
250
  - [`Includes`](source/includes.d.ts) - Returns a boolean for whether the given array includes the given item.
250
251
  - [`Join`](source/join.d.ts) - Join an array of strings and/or numbers using the given string as a delimiter.
251
252
  - [`ArraySlice`](source/array-slice.d.ts) - Returns an array slice of a given range, just like `Array#slice()`.
253
+ - [`ArrayElement`](source/array-element.d.ts) - Extracts the element type of an array or tuple.
252
254
  - [`LastArrayElement`](source/last-array-element.d.ts) - Extract the type of the last element of an array.
253
255
  - [`FixedLengthArray`](source/fixed-length-array.d.ts) - Create a type that represents an array of the given type and length. The `Array` prototype methods that manipulate its length are excluded from the resulting type.
254
256
  - [`MultidimensionalArray`](source/multidimensional-array.d.ts) - Create a type that represents a multidimensional array of the given type and dimensions.
@@ -62,7 +62,7 @@ function displayPetInfo(petInfo: AllUnionFields<Cat | Dog>) {
62
62
  }
63
63
  ```
64
64
 
65
- @see SharedUnionFields
65
+ @see {@link SharedUnionFields}
66
66
 
67
67
  @category Object
68
68
  @category Union
package/source/and.d.ts CHANGED
@@ -46,6 +46,7 @@ type E = And<boolean, boolean>;
46
46
  ```
47
47
 
48
48
  Note: If either of the types is `never`, the result becomes `false`.
49
+
49
50
  @example
50
51
  ```
51
52
  import type {And} from 'type-fest';
@@ -73,6 +74,7 @@ type G = And<never, never>;
73
74
  ```
74
75
 
75
76
  @see {@link Or}
77
+ @see {@link Xor}
76
78
  */
77
79
  export type And<A extends boolean, B extends boolean> = AllExtend<[A, B], true>;
78
80
 
@@ -0,0 +1,46 @@
1
+ import type {UnknownArray} from './unknown-array.d.ts';
2
+
3
+ /**
4
+ Extracts the element type of an array or tuple.
5
+
6
+ Use-cases:
7
+ - When you need type-safe element extraction that returns `never` for non-arrays.
8
+ - When extracting element types from generic array parameters in function signatures.
9
+ - For better readability and explicit intent over using `T[number]` directly.
10
+
11
+ Note: Returns `never` if the type is not an array.
12
+
13
+ @example
14
+ ```
15
+ import type {ArrayElement} from 'type-fest';
16
+
17
+ // Arrays
18
+ type StringArray = ArrayElement<string[]>;
19
+ //=> string
20
+
21
+ // Tuples
22
+ type Tuple = ArrayElement<[1, 2, 3]>;
23
+ //=> 1 | 2 | 3
24
+
25
+ // Type-safe
26
+ type NotArray = ArrayElement<{a: string}>;
27
+ //=> never
28
+
29
+ // Practical example
30
+ declare function getRandomElement<T extends readonly unknown[]>(array: T): ArrayElement<T>;
31
+
32
+ getRandomElement(['foo', 'bar', 'baz'] as const);
33
+ //=> 'foo' | 'bar' | 'baz'
34
+ ```
35
+
36
+ @see {@link ArrayValues} - For directly extracting values from a constant array type.
37
+ @see {@link IterableElement} - For iterables like `Set`, `Map`, and generators (not suitable for all use cases due to different inference behavior).
38
+
39
+ @category Array
40
+ */
41
+ export type ArrayElement<T> =
42
+ T extends UnknownArray
43
+ ? T[number]
44
+ : never;
45
+
46
+ export {};
@@ -1,7 +1,7 @@
1
1
  /**
2
2
  Create a type that represents either the value or an array of the value.
3
3
 
4
- @see Promisable
4
+ @see {@link Promisable}
5
5
 
6
6
  @example
7
7
  ```
@@ -1,12 +1,12 @@
1
1
  import type {ApplyDefaultOptions} from './internal/index.d.ts';
2
- import type {Words} from './words.d.ts';
2
+ import type {Words, WordsOptions} from './words.d.ts';
3
3
 
4
4
  /**
5
5
  CamelCase options.
6
6
 
7
7
  @see {@link CamelCase}
8
8
  */
9
- export type CamelCaseOptions = {
9
+ export type CamelCaseOptions = WordsOptions & {
10
10
  /**
11
11
  Whether to preserved consecutive uppercase letter.
12
12
 
@@ -16,6 +16,7 @@ export type CamelCaseOptions = {
16
16
  };
17
17
 
18
18
  export type _DefaultCamelCaseOptions = {
19
+ splitOnNumbers: true;
19
20
  preserveConsecutiveUppercase: false;
20
21
  };
21
22
 
@@ -83,7 +84,7 @@ export type CamelCase<Type, Options extends CamelCaseOptions = {}> = Type extend
83
84
  ? string extends Type
84
85
  ? Type
85
86
  : Uncapitalize<CamelCaseFromArray<
86
- Words<Type extends Uppercase<Type> ? Lowercase<Type> : Type>,
87
+ Words<Type extends Uppercase<Type> ? Lowercase<Type> : Type, Options>,
87
88
  ApplyDefaultOptions<CamelCaseOptions, _DefaultCamelCaseOptions, Options>
88
89
  >>
89
90
  : Type;
@@ -7,8 +7,8 @@ Convert object properties to camel case recursively.
7
7
 
8
8
  This can be useful when, for example, converting some API types from a different style.
9
9
 
10
- @see CamelCasedProperties
11
- @see CamelCase
10
+ @see {@link CamelCasedProperties}
11
+ @see {@link CamelCase}
12
12
 
13
13
  @example
14
14
  ```
@@ -6,8 +6,8 @@ Convert object properties to camel case but not recursively.
6
6
 
7
7
  This can be useful when, for example, converting some API types from a different style.
8
8
 
9
- @see CamelCasedPropertiesDeep
10
- @see CamelCase
9
+ @see {@link CamelCasedPropertiesDeep}
10
+ @see {@link CamelCase}
11
11
 
12
12
  @example
13
13
  ```
@@ -22,7 +22,7 @@ type AssertCondition<Type, Condition, Options extends ConditionalPickDeepOptions
22
22
  /**
23
23
  ConditionalPickDeep options.
24
24
 
25
- @see ConditionalPickDeep
25
+ @see {@link ConditionalPickDeep}
26
26
  */
27
27
  export type ConditionalPickDeepOptions = {
28
28
  /**
@@ -40,7 +40,7 @@ type DefaultConditionalPickDeepOptions = {
40
40
  /**
41
41
  Pick keys recursively from the shape that matches the given condition.
42
42
 
43
- @see ConditionalPick
43
+ @see {@link ConditionalPick}
44
44
 
45
45
  @example
46
46
  ```
@@ -61,7 +61,7 @@ type SimplifyDeepTypeAB = ConditionalSimplifyDeep<TypeA & TypeB, SomeComplexType
61
61
  // }
62
62
  ```
63
63
 
64
- @see SimplifyDeep
64
+ @see {@link SimplifyDeep}
65
65
  @category Object
66
66
  */
67
67
  export type ConditionalSimplifyDeep<Type, ExcludeType = never, IncludeType = unknown> = Type extends ExcludeType
@@ -38,7 +38,7 @@ type C = Simplify<{a: number} & {b: string}>;
38
38
  //=> {a: number; b: string}
39
39
  ```
40
40
 
41
- @see ConditionalSimplifyDeep
41
+ @see {@link ConditionalSimplifyDeep}
42
42
  @category Object
43
43
  */
44
44
  export type ConditionalSimplify<Type, ExcludeType = never, IncludeType = unknown> = Type extends ExcludeType
@@ -27,8 +27,8 @@ Convert a string literal to a custom string delimiter casing.
27
27
 
28
28
  This can be useful when, for example, converting a camel-cased object property to an oddly cased one.
29
29
 
30
- @see KebabCase
31
- @see SnakeCase
30
+ @see {@link KebabCase}
31
+ @see {@link SnakeCase}
32
32
 
33
33
  @example
34
34
  ```
@@ -8,8 +8,8 @@ Convert object properties to delimiter case recursively.
8
8
 
9
9
  This can be useful when, for example, converting some API types from a different style.
10
10
 
11
- @see DelimiterCase
12
- @see DelimiterCasedProperties
11
+ @see {@link DelimiterCase}
12
+ @see {@link DelimiterCasedProperties}
13
13
 
14
14
  @example
15
15
  ```
@@ -7,8 +7,8 @@ Convert object properties to delimiter case but not recursively.
7
7
 
8
8
  This can be useful when, for example, converting some API types from a different style.
9
9
 
10
- @see DelimiterCase
11
- @see DelimiterCasedPropertiesDeep
10
+ @see {@link DelimiterCase}
11
+ @see {@link DelimiterCasedPropertiesDeep}
12
12
 
13
13
  @example
14
14
  ```
@@ -40,7 +40,7 @@ type Fail = IsEmptyObject<[]>; //=> false
40
40
  type Fail = IsEmptyObject<null>; //=> false
41
41
  ```
42
42
 
43
- @see EmptyObject
43
+ @see {@link EmptyObject}
44
44
  @category Object
45
45
  */
46
46
  export type IsEmptyObject<T> = T extends EmptyObject ? true : false;
package/source/exact.d.ts CHANGED
@@ -1,4 +1,5 @@
1
- import type {ArrayElement, ObjectValue} from './internal/index.d.ts';
1
+ import type {ObjectValue} from './internal/index.d.ts';
2
+ import type {ArrayElement} from './array-element.d.ts';
2
3
  import type {IsEqual} from './is-equal.d.ts';
3
4
  import type {KeysOfUnion} from './keys-of-union.d.ts';
4
5
  import type {IsUnknown} from './is-unknown.d.ts';
@@ -1,6 +1,7 @@
1
1
  import type {SplitOnRestElement} from './split-on-rest-element.d.ts';
2
2
  import type {IsArrayReadonly} from './internal/array.d.ts';
3
3
  import type {UnknownArray} from './unknown-array.d.ts';
4
+ import type {IfNotAnyOrNever} from './internal/type.d.ts';
4
5
 
5
6
  /**
6
7
  Create a tuple with the [`rest`](https://www.typescriptlang.org/docs/handbook/2/objects.html#tuple-types) element removed.
@@ -22,16 +23,18 @@ type T4 = ExcludeRestElement<[number, string]>;
22
23
  //=> [number, string]
23
24
  ```
24
25
 
25
- @see ExtractRestElement, SplitOnRestElement
26
+ @see {@link ExtractRestElement}
27
+ @see {@link SplitOnRestElement}
26
28
  @category Array
27
29
  */
28
- export type ExcludeRestElement<Array_ extends UnknownArray> =
30
+ export type ExcludeRestElement<Array_ extends UnknownArray> = IfNotAnyOrNever<Array_,
29
31
  SplitOnRestElement<Array_> extends infer Result
30
32
  ? Result extends readonly UnknownArray[]
31
33
  ? IsArrayReadonly<Array_> extends true
32
34
  ? Readonly<[...Result[0], ...Result[2]]>
33
35
  : [...Result[0], ...Result[2]]
34
- : Result
35
- : never;
36
+ : never
37
+ : never
38
+ >;
36
39
 
37
40
  export {};
@@ -0,0 +1,113 @@
1
+ import type {If} from './if.d.ts';
2
+ import type {IfNotAnyOrNever, MapsSetsOrArrays, NonRecursiveType} from './internal/type.d.ts';
3
+ import type {IsUnknown} from './is-unknown.d.ts';
4
+ import type {KeysOfUnion} from './keys-of-union.d.ts';
5
+ import type {Simplify} from './simplify.d.ts';
6
+
7
+ /**
8
+ Ensure mutual exclusivity in object unions by adding other members’ keys as `?: never`.
9
+
10
+ Use-cases:
11
+ - You want each union member to be exclusive, preventing overlapping object shapes.
12
+ - You want to safely access any property defined across the union without additional type guards.
13
+
14
+ @example
15
+ ```
16
+ import type {ExclusifyUnion} from 'type-fest';
17
+
18
+ type FileConfig = {
19
+ filePath: string;
20
+ };
21
+
22
+ type InlineConfig = {
23
+ content: string;
24
+ };
25
+
26
+ declare function loadConfig1(options: FileConfig | InlineConfig): void;
27
+
28
+ // Someone could mistakenly provide both `filePath` and `content`.
29
+ loadConfig1({filePath: './config.json', content: '{ "name": "app" }'}); // No errors
30
+
31
+ // Use `ExclusifyUnion` to prevent that mistake.
32
+ type Config = ExclusifyUnion<FileConfig | InlineConfig>;
33
+ //=> {filePath: string; content?: never} | {content: string; filePath?: never}
34
+
35
+ declare function loadConfig2(options: Config): void;
36
+
37
+ // @ts-expect-error
38
+ loadConfig2({filePath: './config.json', content: '{ "name": "app" }'});
39
+ //=> Error: Argument of type '{ filePath: string; content: string; }' is not assignable to parameter of type '{ filePath: string; content?: never; } | { content: string; filePath?: never; }'.
40
+
41
+ loadConfig2({filePath: './config.json'}); // Ok
42
+
43
+ loadConfig2({content: '{ "name": "app" }'}); // Ok
44
+ ```
45
+
46
+ @example
47
+ ```
48
+ import type {ExclusifyUnion} from 'type-fest';
49
+
50
+ type CardPayment = {
51
+ amount: number;
52
+ cardNumber: string;
53
+ };
54
+
55
+ type PaypalPayment = {
56
+ amount: number;
57
+ paypalId: string;
58
+ };
59
+
60
+ function processPayment1(payment: CardPayment | PaypalPayment) {
61
+ // @ts-expect-error
62
+ const details = payment.cardNumber ?? payment.paypalId; // Cannot access `cardNumber` or `paypalId` directly
63
+ }
64
+
65
+ type Payment = ExclusifyUnion<CardPayment | PaypalPayment>;
66
+ //=> {amount: number; cardNumber: string; paypalId?: never} | {amount: number; paypalId: string; cardNumber?: never}
67
+
68
+ function processPayment2(payment: Payment) {
69
+ const details = payment.cardNumber ?? payment.paypalId; // Ok
70
+ //=> string
71
+ }
72
+ ```
73
+
74
+ @example
75
+ ```
76
+ import type {ExclusifyUnion} from 'type-fest';
77
+
78
+ type A = ExclusifyUnion<{a: string} | {b: number}>;
79
+ //=> {a: string; b?: never} | {a?: never; b: number}
80
+
81
+ type B = ExclusifyUnion<{a: string} | {b: number} | {c: boolean}>;
82
+ //=> {a: string; b?: never; c?: never} | {a?: never; b: number; c?: never} | {a?: never; b?: never; c: boolean}
83
+
84
+ type C = ExclusifyUnion<{a: string; b: number} | {b: string; c: number}>;
85
+ //=> {a: string; b: number; c?: never} | {a?: never; b: string; c: number}
86
+
87
+ type D = ExclusifyUnion<{a?: 1; readonly b: 2} | {d: 4}>;
88
+ //=> {a?: 1; readonly b: 2; d?: never} | {a?: never; b?: never; d: 4}
89
+ ```
90
+
91
+ @category Object
92
+ @category Union
93
+ */
94
+ export type ExclusifyUnion<Union> = IfNotAnyOrNever<Union,
95
+ If<IsUnknown<Union>, Union,
96
+ Extract<Union, NonRecursiveType | MapsSetsOrArrays> extends infer SkippedMembers
97
+ ? SkippedMembers | _ExclusifyUnion<Exclude<Union, SkippedMembers>>
98
+ : never
99
+ >
100
+ >;
101
+
102
+ type _ExclusifyUnion<Union, UnionCopy = Union> = Union extends unknown // For distributing `Union`
103
+ ? Simplify<
104
+ Union & Partial<
105
+ Record<
106
+ Exclude<KeysOfUnion<UnionCopy>, keyof Union>,
107
+ never
108
+ >
109
+ >
110
+ >
111
+ : never; // Should never happen
112
+
113
+ export {};
@@ -21,7 +21,8 @@ type T4 = ExtractRestElement<[number, string]>;
21
21
  //=> never
22
22
  ```
23
23
 
24
- @see ExcludeRestElement, SplitOnRestElement
24
+ @see {@link ExcludeRestElement}
25
+ @see {@link SplitOnRestElement}
25
26
  @category Array
26
27
  */
27
28
  export type ExtractRestElement<T extends UnknownArray> = SplitOnRestElement<T>[1][number];
@@ -1,7 +1,7 @@
1
1
  /**
2
2
  A stricter version of {@link Extract<T, U>} that ensures every member of `U` can successfully extract something from `T`.
3
3
 
4
- For example, `StrictExtract<string | number | boolean, number | bigint>` will error because `bigint` cannot extract anything from `string | number | boolean`.
4
+ For example, `ExtractStrict<string | number | boolean, number | bigint>` will error because `bigint` cannot extract anything from `string | number | boolean`.
5
5
 
6
6
  @example
7
7
  ```
@@ -19,6 +19,12 @@ GreaterThanOrEqual<1, 5>;
19
19
  */
20
20
  export type GreaterThanOrEqual<A extends number, B extends number> = number extends A | B
21
21
  ? never
22
- : A extends B ? true : GreaterThan<A, B>;
22
+ : A extends number // For distributing `A`
23
+ ? B extends number // For distributing `B`
24
+ ? A extends B
25
+ ? true
26
+ : GreaterThan<A, B>
27
+ : never // Should never happen
28
+ : never; // Should never happen
23
29
 
24
30
  export {};
package/source/if.d.ts CHANGED
@@ -54,6 +54,41 @@ type B = IfEqual<string, number, 'equal', 'not equal'>;
54
54
  //=> 'not equal'
55
55
  ```
56
56
 
57
+ Note: Sometimes using the `If` type can make an implementation non–tail-recursive, which can impact performance. In such cases, it’s better to use a conditional directly. Refer to the following example:
58
+
59
+ @example
60
+ ```
61
+ import type {If, IsEqual, StringRepeat} from 'type-fest';
62
+
63
+ type HundredZeroes = StringRepeat<'0', 100>;
64
+
65
+ // The following implementation is not tail recursive
66
+ type Includes<S extends string, Char extends string> =
67
+ S extends `${infer First}${infer Rest}`
68
+ ? If<IsEqual<First, Char>,
69
+ 'found',
70
+ Includes<Rest, Char>>
71
+ : 'not found';
72
+
73
+ // Hence, instantiations with long strings will fail
74
+ // @ts-expect-error
75
+ type Fails = Includes<HundredZeroes, '1'>;
76
+ // ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
77
+ // Error: Type instantiation is excessively deep and possibly infinite.
78
+
79
+ // However, if we use a simple conditional instead of `If`, the implementation becomes tail-recursive
80
+ type IncludesWithoutIf<S extends string, Char extends string> =
81
+ S extends `${infer First}${infer Rest}`
82
+ ? IsEqual<First, Char> extends true
83
+ ? 'found'
84
+ : IncludesWithoutIf<Rest, Char>
85
+ : 'not found';
86
+
87
+ // Now, instantiations with long strings will work
88
+ type Works = IncludesWithoutIf<HundredZeroes, '1'>;
89
+ //=> 'not found'
90
+ ```
91
+
57
92
  @category Type Guard
58
93
  @category Utilities
59
94
  */
@@ -30,7 +30,7 @@ type ZeroToNine = IntClosedRange<0, 9>;
30
30
  type Hundreds = IntClosedRange<100, 900, 100>;
31
31
  ```
32
32
 
33
- @see IntRange
33
+ @see {@link IntRange}
34
34
  */
35
35
  export type IntClosedRange<Start extends number, End extends number, Skip extends number = 1> = IntRange<Start, Sum<End, 1>, Skip>;
36
36
 
@@ -30,7 +30,7 @@ type ZeroToNine = IntRange<0, 10>;
30
30
  type Hundreds = IntRange<100, 901, 100>;
31
31
  ```
32
32
 
33
- @see IntClosedRange
33
+ @see {@link IntClosedRange}
34
34
  */
35
35
  export type IntRange<Start extends number, End extends number, Step extends number = 1> = PrivateIntRange<Start, End, Step>;
36
36
 
@@ -24,15 +24,6 @@ export type FirstArrayElement<TArray extends UnknownArrayOrTuple> = TArray exten
24
24
  ? THead
25
25
  : never;
26
26
 
27
- /**
28
- Extract the element of an array that also works for array union.
29
-
30
- Returns `never` if T is not an array.
31
-
32
- It creates a type-safe way to access the element type of `unknown` type.
33
- */
34
- export type ArrayElement<T> = T extends readonly unknown[] ? T[0] : never;
35
-
36
27
  /**
37
28
  Returns the static, fixed-length portion of the given array, excluding variable-length parts.
38
29
 
@@ -2,6 +2,7 @@ import type {If} from '../if.d.ts';
2
2
  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
+ import type {UnknownArray} from '../unknown-array.d.ts';
5
6
 
6
7
  /**
7
8
  Matches any primitive, `void`, `Date`, or `RegExp` value.
@@ -13,6 +14,11 @@ Matches non-recursive types.
13
14
  */
14
15
  export type NonRecursiveType = BuiltIns | Function | (new (...arguments_: any[]) => unknown);
15
16
 
17
+ /**
18
+ Matches maps, sets, or arrays.
19
+ */
20
+ export type MapsSetsOrArrays = ReadonlyMap<unknown, unknown> | WeakMap<WeakKey, unknown> | ReadonlySet<unknown> | WeakSet<WeakKey> | UnknownArray;
21
+
16
22
  /**
17
23
  Returns a boolean for whether the two given types extends the base type.
18
24
  */
@@ -96,6 +102,32 @@ type B = IfNotAnyOrNever<any, 'VALID', 'IS_ANY', 'IS_NEVER'>;
96
102
  type C = IfNotAnyOrNever<never, 'VALID', 'IS_ANY', 'IS_NEVER'>;
97
103
  //=> 'IS_NEVER'
98
104
  ```
105
+
106
+ Note: Wrapping a tail-recursive type with `IfNotAnyOrNever` makes the implementation non-tail-recursive. To fix this, move the recursion into a helper type. Refer to the following example:
107
+
108
+ @example
109
+ ```ts
110
+ import type {StringRepeat} from 'type-fest';
111
+
112
+ type NineHundredNinetyNineSpaces = StringRepeat<' ', 999>;
113
+
114
+ // The following implementation is not tail recursive
115
+ type TrimLeft<S extends string> = IfNotAnyOrNever<S, S extends ` ${infer R}` ? TrimLeft<R> : S>;
116
+
117
+ // Hence, instantiations with long strings will fail
118
+ // @ts-expect-error
119
+ type T1 = TrimLeft<NineHundredNinetyNineSpaces>;
120
+ // ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
121
+ // Error: Type instantiation is excessively deep and possibly infinite.
122
+
123
+ // To fix this, move the recursion into a helper type
124
+ type TrimLeftOptimised<S extends string> = IfNotAnyOrNever<S, _TrimLeftOptimised<S>>;
125
+
126
+ type _TrimLeftOptimised<S extends string> = S extends ` ${infer R}` ? _TrimLeftOptimised<R> : S;
127
+
128
+ type T2 = TrimLeftOptimised<NineHundredNinetyNineSpaces>;
129
+ //=> ''
130
+ ```
99
131
  */
100
132
  export type IfNotAnyOrNever<T, IfNotAnyOrNever, IfAny = any, IfNever = never> =
101
133
  If<IsAny<T>, IfAny, If<IsNever<T>, IfNever, IfNotAnyOrNever>>;
@@ -8,8 +8,8 @@ Convert object properties to kebab case recursively.
8
8
 
9
9
  This can be useful when, for example, converting some API types from a different style.
10
10
 
11
- @see KebabCase
12
- @see KebabCasedProperties
11
+ @see {@link KebabCase}
12
+ @see {@link KebabCasedProperties}
13
13
 
14
14
  @example
15
15
  ```
@@ -8,8 +8,8 @@ Convert object properties to kebab case but not recursively.
8
8
 
9
9
  This can be useful when, for example, converting some API types from a different style.
10
10
 
11
- @see KebabCase
12
- @see KebabCasedPropertiesDeep
11
+ @see {@link KebabCase}
12
+ @see {@link KebabCasedPropertiesDeep}
13
13
 
14
14
  @example
15
15
  ```
@@ -6,7 +6,7 @@ Like `LiteralToPrimitive` except it converts literal types inside an object or a
6
6
 
7
7
  For example, given a constant object, it returns a new object type with the same keys but with all the values converted to primitives.
8
8
 
9
- @see LiteralToPrimitive
9
+ @see {@link LiteralToPrimitive}
10
10
 
11
11
  Use-case: Deal with data that is imported from a JSON file.
12
12
 
@@ -10,7 +10,7 @@ Matches the hidden `Infinity` type.
10
10
 
11
11
  Please upvote [this issue](https://github.com/microsoft/TypeScript/issues/32277) if you want to have this type as a built-in in TypeScript.
12
12
 
13
- @see NegativeInfinity
13
+ @see {@link NegativeInfinity}
14
14
 
15
15
  @category Numeric
16
16
  */
@@ -23,7 +23,7 @@ Matches the hidden `-Infinity` type.
23
23
 
24
24
  Please upvote [this issue](https://github.com/microsoft/TypeScript/issues/32277) if you want to have this type as a built-in in TypeScript.
25
25
 
26
- @see PositiveInfinity
26
+ @see {@link PositiveInfinity}
27
27
 
28
28
  @category Numeric
29
29
  */
@@ -88,8 +88,8 @@ import type {Integer} from 'type-fest';
88
88
  declare function setYear<T extends number>(length: Integer<T>): void;
89
89
  ```
90
90
 
91
- @see NegativeInteger
92
- @see NonNegativeInteger
91
+ @see {@link NegativeInteger}
92
+ @see {@link NonNegativeInteger}
93
93
 
94
94
  @category Numeric
95
95
  */
@@ -114,7 +114,7 @@ import type {Float} from 'type-fest';
114
114
  declare function setPercentage<T extends number>(length: Float<T>): void;
115
115
  ```
116
116
 
117
- @see Integer
117
+ @see {@link Integer}
118
118
 
119
119
  @category Numeric
120
120
  */
@@ -129,8 +129,8 @@ Equivalent to `Negative<Float<T>>`.
129
129
 
130
130
  Use-case: Validating and documenting parameters.
131
131
 
132
- @see Negative
133
- @see Float
132
+ @see {@link Negative}
133
+ @see {@link Float}
134
134
 
135
135
  @category Numeric
136
136
  */
@@ -141,8 +141,8 @@ A negative `number`/`bigint` (`-∞ < x < 0`)
141
141
 
142
142
  Use-case: Validating and documenting parameters.
143
143
 
144
- @see NegativeInteger
145
- @see NonNegative
144
+ @see {@link NegativeInteger}
145
+ @see {@link NonNegative}
146
146
 
147
147
  @category Numeric
148
148
  */
@@ -156,8 +156,8 @@ You can't pass a `bigint` as they are already guaranteed to be integers, instead
156
156
 
157
157
  Use-case: Validating and documenting parameters.
158
158
 
159
- @see Negative
160
- @see Integer
159
+ @see {@link Negative}
160
+ @see {@link Integer}
161
161
 
162
162
  @category Numeric
163
163
  */
@@ -168,8 +168,8 @@ A non-negative `number`/`bigint` (`0 <= x < ∞`).
168
168
 
169
169
  Use-case: Validating and documenting parameters.
170
170
 
171
- @see NonNegativeInteger
172
- @see Negative
171
+ @see {@link NonNegativeInteger}
172
+ @see {@link Negative}
173
173
 
174
174
  @example
175
175
  ```
@@ -190,8 +190,8 @@ You can't pass a `bigint` as they are already guaranteed to be integers, instead
190
190
 
191
191
  Use-case: Validating and documenting parameters.
192
192
 
193
- @see NonNegative
194
- @see Integer
193
+ @see {@link NonNegative}
194
+ @see {@link Integer}
195
195
 
196
196
  @example
197
197
  ```
@@ -207,7 +207,7 @@ export type NonNegativeInteger<T extends number> = NonNegative<Integer<T>>;
207
207
  /**
208
208
  Returns a boolean for whether the given number is a negative number.
209
209
 
210
- @see Negative
210
+ @see {@link Negative}
211
211
 
212
212
  @example
213
213
  ```
@@ -85,7 +85,7 @@ type ExampleWithoutIndexSignatures = OmitIndexSignature<Example>;
85
85
  // => { foo: 'bar'; qux?: 'baz' | undefined; }
86
86
  ```
87
87
 
88
- @see PickIndexSignature
88
+ @see {@link PickIndexSignature}
89
89
  @category Object
90
90
  */
91
91
  export type OmitIndexSignature<ObjectType> = {
package/source/or.d.ts CHANGED
@@ -2,15 +2,15 @@ import type {If} from './if.d.ts';
2
2
  import type {IsNever} from './is-never.d.ts';
3
3
 
4
4
  /**
5
- Returns a boolean for whether either of two given types are true.
5
+ Returns a boolean for whether either of two given types is true.
6
6
 
7
- Use-case: Constructing complex conditional types where multiple conditions must be satisfied.
7
+ Use-case: Constructing complex conditional types where at least one condition must be satisfied.
8
8
 
9
9
  @example
10
10
  ```
11
11
  import type {Or} from 'type-fest';
12
12
 
13
- type TT = Or<true, false>;
13
+ type TT = Or<true, true>;
14
14
  //=> true
15
15
 
16
16
  type TF = Or<true, false>;
@@ -24,10 +24,11 @@ type FF = Or<false, false>;
24
24
  ```
25
25
 
26
26
  Note: When `boolean` is passed as an argument, it is distributed into separate cases, and the final result is a union of those cases.
27
- For example, `And<false, boolean>` expands to `And<false, true> | And<false, false>`, which simplifies to `true | false` (i.e., `boolean`).
27
+ For example, `Or<false, boolean>` expands to `Or<false, true> | Or<false, false>`, which simplifies to `true | false` (i.e., `boolean`).
28
+
28
29
  @example
29
30
  ```
30
- import type {And} from 'type-fest';
31
+ import type {Or} from 'type-fest';
31
32
 
32
33
  type A = Or<false, boolean>;
33
34
  //=> boolean
@@ -74,6 +75,7 @@ type G = Or<never, never>;
74
75
  ```
75
76
 
76
77
  @see {@link And}
78
+ @see {@link Xor}
77
79
  */
78
80
  export type Or<A extends boolean, B extends boolean> =
79
81
  _Or<If<IsNever<A>, false, A>, If<IsNever<B>, false, B>>; // `never` is treated as `false`
@@ -208,6 +208,15 @@ export namespace PackageJson {
208
208
  */
209
209
  type Dependency = Partial<Record<string, string>>;
210
210
 
211
+ /**
212
+ Specifies requirements for development environment components such as operating systems, runtimes, or package managers. Used to ensure consistent development environments across the team.
213
+ */
214
+ type DevEngineDependency = {
215
+ name: string;
216
+ version?: string;
217
+ onFail?: 'ignore' | 'warn' | 'error' | 'download';
218
+ };
219
+
211
220
  /**
212
221
  A mapping of conditions and the paths to which they resolve.
213
222
  */
@@ -563,6 +572,17 @@ export namespace PackageJson {
563
572
  string
564
573
  >>;
565
574
 
575
+ /**
576
+ Define the runtime and package manager for developing the current project.
577
+ */
578
+ devEngines?: {
579
+ os?: DevEngineDependency | DevEngineDependency[];
580
+ cpu?: DevEngineDependency | DevEngineDependency[];
581
+ libc?: DevEngineDependency | DevEngineDependency[];
582
+ runtime?: DevEngineDependency | DevEngineDependency[];
583
+ packageManager?: DevEngineDependency | DevEngineDependency[];
584
+ };
585
+
566
586
  /**
567
587
  If set to `true`, a warning will be shown if package is installed locally. Useful if the package is primarily a command-line application that should be installed globally.
568
588
 
@@ -4,7 +4,7 @@ import type {IsUnknown} from './is-unknown.d.ts';
4
4
  import type {Merge} from './merge.d.ts';
5
5
 
6
6
  /**
7
- @see PartialOnUndefinedDeep
7
+ @see {@link PartialOnUndefinedDeep}
8
8
  */
9
9
  export type PartialOnUndefinedDeepOptions = {
10
10
  /**
@@ -7,8 +7,8 @@ Convert object properties to pascal case recursively.
7
7
 
8
8
  This can be useful when, for example, converting some API types from a different style.
9
9
 
10
- @see PascalCase
11
- @see PascalCasedProperties
10
+ @see {@link PascalCase}
11
+ @see {@link PascalCasedProperties}
12
12
 
13
13
  @example
14
14
  ```
@@ -7,8 +7,8 @@ Convert object properties to pascal case but not recursively.
7
7
 
8
8
  This can be useful when, for example, converting some API types from a different style.
9
9
 
10
- @see PascalCase
11
- @see PascalCasedPropertiesDeep
10
+ @see {@link PascalCase}
11
+ @see {@link PascalCasedPropertiesDeep}
12
12
 
13
13
  @example
14
14
  ```
@@ -40,7 +40,7 @@ type ExampleIndexSignature = PickIndexSignature<Example>;
40
40
  // }
41
41
  ```
42
42
 
43
- @see OmitIndexSignature
43
+ @see {@link OmitIndexSignature}
44
44
  @category Object
45
45
  */
46
46
  export type PickIndexSignature<ObjectType> = {
@@ -81,7 +81,7 @@ function displayPetInfo(petInfo: SharedUnionFieldsDeep<Cat | Dog>['info']) {
81
81
  }
82
82
  ```
83
83
 
84
- @see SharedUnionFields
84
+ @see {@link SharedUnionFields}
85
85
 
86
86
  @category Object
87
87
  @category Union
@@ -59,8 +59,8 @@ function displayPetInfo(petInfo: SharedUnionFields<Cat | Dog>) {
59
59
  }
60
60
  ```
61
61
 
62
- @see SharedUnionFieldsDeep
63
- @see AllUnionFields
62
+ @see {@link SharedUnionFieldsDeep}
63
+ @see {@link AllUnionFields}
64
64
 
65
65
  @category Object
66
66
  @category Union
@@ -104,7 +104,7 @@ type SimplifyDeepProperties = SimplifyDeep<Properties1 & Properties2, ComplexTyp
104
104
  // };
105
105
  ```
106
106
 
107
- @see Simplify
107
+ @see {@link Simplify}
108
108
  @category Object
109
109
  */
110
110
  export type SimplifyDeep<Type, ExcludeType = never> =
@@ -52,7 +52,7 @@ fn(someInterface as Simplify<SomeInterface>); // Good: transform an `interface`
52
52
  ```
53
53
 
54
54
  @link https://github.com/microsoft/TypeScript/issues/15300
55
- @see SimplifyDeep
55
+ @see {@link SimplifyDeep}
56
56
  @category Object
57
57
  */
58
58
  export type Simplify<T> = {[KeyType in keyof T]: T[KeyType]} & {};
@@ -8,8 +8,8 @@ Convert object properties to snake case recursively.
8
8
 
9
9
  This can be useful when, for example, converting some API types from a different style.
10
10
 
11
- @see SnakeCase
12
- @see SnakeCasedProperties
11
+ @see {@link SnakeCase}
12
+ @see {@link SnakeCasedProperties}
13
13
 
14
14
  @example
15
15
  ```
@@ -8,8 +8,8 @@ Convert object properties to snake case but not recursively.
8
8
 
9
9
  This can be useful when, for example, converting some API types from a different style.
10
10
 
11
- @see SnakeCase
12
- @see SnakeCasedPropertiesDeep
11
+ @see {@link SnakeCase}
12
+ @see {@link SnakeCasedPropertiesDeep}
13
13
 
14
14
  @example
15
15
  ```
@@ -56,8 +56,8 @@ type T5 = SplitOnRestElement<readonly [string?, ...number[]], {preserveOptionalM
56
56
  //=> readonly [[string], number[], []] or readonly [[string | undefined], number[], []]
57
57
  ```
58
58
 
59
- @see ExtractRestElement
60
- @see ExcludeRestElement
59
+ @see {@link ExtractRestElement}
60
+ @see {@link ExcludeRestElement}
61
61
  @category Array
62
62
  */
63
63
  export type SplitOnRestElement<
@@ -23,7 +23,7 @@ writableDeepFoo.b = ['something'];
23
23
 
24
24
  Note that types containing overloaded functions are not made deeply writable due to a [TypeScript limitation](https://github.com/microsoft/TypeScript/issues/29732).
25
25
 
26
- @see Writable
26
+ @see {@link Writable}
27
27
  @category Object
28
28
  @category Array
29
29
  @category Set