type-fest 4.28.0 → 4.29.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/index.d.ts CHANGED
@@ -66,7 +66,7 @@ export type {SimplifyDeep} from './source/simplify-deep';
66
66
  export type {Jsonify} from './source/jsonify';
67
67
  export type {Jsonifiable} from './source/jsonifiable';
68
68
  export type {StructuredCloneable} from './source/structured-cloneable';
69
- export type {Schema} from './source/schema';
69
+ export type {Schema, SchemaOptions} from './source/schema';
70
70
  export type {LiteralToPrimitive} from './source/literal-to-primitive';
71
71
  export type {LiteralToPrimitiveDeep} from './source/literal-to-primitive-deep';
72
72
  export type {
@@ -106,6 +106,7 @@ export type {IsFloat} from './source/is-float';
106
106
  export type {TupleToUnion} from './source/tuple-to-union';
107
107
  export type {UnionToTuple} from './source/union-to-tuple';
108
108
  export type {IntRange} from './source/int-range';
109
+ export type {IntClosedRange} from './source/int-closed-range';
109
110
  export type {IsEqual} from './source/is-equal';
110
111
  export type {
111
112
  IsLiteral,
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "type-fest",
3
- "version": "4.28.0",
3
+ "version": "4.29.0",
4
4
  "description": "A collection of essential TypeScript types",
5
5
  "license": "(MIT OR CC0-1.0)",
6
6
  "repository": "sindresorhus/type-fest",
package/readme.md CHANGED
@@ -192,6 +192,8 @@ Click the type names for complete docs.
192
192
  - [`Spread`](source/spread.d.ts) - Mimic the type inferred by TypeScript when merging two objects or two arrays/tuples using the spread syntax.
193
193
  - [`IsEqual`](source/is-equal.d.ts) - Returns a boolean for whether the two given types are equal.
194
194
  - [`TaggedUnion`](source/tagged-union.d.ts) - Create a union of types that share a common discriminant property.
195
+ - [`IntRange`](source/int-range.d.ts) - Generate a union of numbers (includes the start and excludes the end).
196
+ - [`IntClosedRange`](source/int-closed-range.d.ts) - Generate a union of numbers (includes the start and the end).
195
197
  - [`IntRange`](source/int-range.d.ts) - Generate a union of numbers.
196
198
  - [`ArrayIndices`](source/array-indices.d.ts) - Provides valid indices for a constant array or tuple.
197
199
  - [`ArrayValues`](source/array-values.d.ts) - Provides all values for a constant array or tuple.
@@ -0,0 +1,35 @@
1
+ import type {IntRange} from './int-range';
2
+ import type {Sum} from './sum';
3
+
4
+ /**
5
+ Generate a union of numbers.
6
+
7
+ The numbers are created from the given `Start` (inclusive) parameter to the given `End` (inclusive) parameter.
8
+
9
+ You skip over numbers using the `Step` parameter (defaults to `1`). For example, `IntClosedRange<0, 10, 2>` will create a union of `0 | 2 | 4 | 6 | 8 | 10`.
10
+
11
+ Note: `Start` or `End` must be non-negative and smaller than `999`.
12
+
13
+ Use-cases:
14
+ 1. This can be used to define a set of valid input/output values. for example:
15
+ ```
16
+ type Age = IntClosedRange<0, 120>; //=> 0 | 1 | 2 | ... | 119 | 120
17
+ type FontSize = IntClosedRange<10, 20>; //=> 10 | 11 | ... | 19 | 20
18
+ type EvenNumber = IntClosedRange<0, 10, 2>; //=> 0 | 2 | 4 | 6 | 8 | 10
19
+ ```
20
+ 2. This can be used to define random numbers in a range. For example, `type RandomNumber = IntClosedRange<0, 100>;`
21
+
22
+ @example
23
+ ```
24
+ import type {IntClosedRange} from 'type-fest';
25
+
26
+ // Create union type `0 | 1 | ... | 9`
27
+ type ZeroToNine = IntClosedRange<0, 9>;
28
+
29
+ // Create union type `100 | 200 | 300 | ... | 900`
30
+ type Hundreds = IntClosedRange<100, 900, 100>;
31
+ ```
32
+
33
+ @see IntRange
34
+ */
35
+ export type IntClosedRange<Start extends number, End extends number, Skip extends number = 1> = IntRange<Start, Sum<End, 1>, Skip>;
@@ -29,6 +29,8 @@ type ZeroToNine = IntRange<0, 10>;
29
29
  // Create union type `100 | 200 | 300 | ... | 900`
30
30
  type Hundreds = IntRange<100, 901, 100>;
31
31
  ```
32
+
33
+ @see IntClosedRange
32
34
  */
33
35
  export type IntRange<Start extends number, End extends number, Step extends number = 1> = PrivateIntRange<Start, End, Step>;
34
36
 
@@ -19,6 +19,7 @@ interface User {
19
19
  created: Date;
20
20
  active: boolean;
21
21
  passwordHash: string;
22
+ attributes: ['Foo', 'Bar']
22
23
  }
23
24
 
24
25
  type UserMask = Schema<User, 'mask' | 'hide' | 'show'>;
@@ -32,12 +33,13 @@ const userMaskSettings: UserMask = {
32
33
  created: 'show',
33
34
  active: 'show',
34
35
  passwordHash: 'hide',
36
+ attributes: ['mask', 'show']
35
37
  }
36
38
  ```
37
39
 
38
40
  @category Object
39
41
  */
40
- export type Schema<ObjectType, ValueType> = ObjectType extends string
42
+ export type Schema<ObjectType, ValueType, Options extends SchemaOptions = {}> = ObjectType extends string
41
43
  ? ValueType
42
44
  : ObjectType extends Map<unknown, unknown>
43
45
  ? ValueType
@@ -48,7 +50,9 @@ export type Schema<ObjectType, ValueType> = ObjectType extends string
48
50
  : ObjectType extends ReadonlySet<unknown>
49
51
  ? ValueType
50
52
  : ObjectType extends Array<infer U>
51
- ? Array<Schema<U, ValueType>>
53
+ ? Options['recurseIntoArrays'] extends false | undefined
54
+ ? ValueType
55
+ : Array<Schema<U, ValueType>>
52
56
  : ObjectType extends (...arguments_: unknown[]) => unknown
53
57
  ? ValueType
54
58
  : ObjectType extends Date
@@ -58,14 +62,53 @@ export type Schema<ObjectType, ValueType> = ObjectType extends string
58
62
  : ObjectType extends RegExp
59
63
  ? ValueType
60
64
  : ObjectType extends object
61
- ? SchemaObject<ObjectType, ValueType>
65
+ ? SchemaObject<ObjectType, ValueType, Options>
62
66
  : ValueType;
63
67
 
64
68
  /**
65
69
  Same as `Schema`, but accepts only `object`s as inputs. Internal helper for `Schema`.
66
70
  */
67
- type SchemaObject<ObjectType extends object, K> = {
68
- [KeyType in keyof ObjectType]: ObjectType[KeyType] extends readonly unknown[] | unknown[]
69
- ? Schema<ObjectType[KeyType], K>
70
- : Schema<ObjectType[KeyType], K> | K;
71
+ type SchemaObject<
72
+ ObjectType extends object,
73
+ K,
74
+ Options extends SchemaOptions,
75
+ > = {
76
+ [KeyType in keyof ObjectType]: ObjectType[KeyType] extends
77
+ | readonly unknown[]
78
+ | unknown[]
79
+ ? Options['recurseIntoArrays'] extends false | undefined
80
+ ? K
81
+ : Schema<ObjectType[KeyType], K, Options>
82
+ : Schema<ObjectType[KeyType], K, Options> | K;
83
+ };
84
+
85
+ /**
86
+ @see Schema
87
+ */
88
+ export type SchemaOptions = {
89
+ /**
90
+ By default, this affects elements in array and tuple types. You can change this by passing `{recurseIntoArrays: false}` as the third type argument:
91
+ - If `recurseIntoArrays` is set to `true` (default), array elements will be recursively processed as well.
92
+ - If `recurseIntoArrays` is set to `false`, arrays will not be recursively processed, and the entire array will be replaced with the given value type.
93
+
94
+ @example
95
+ ```
96
+ type UserMask = Schema<User, 'mask' | 'hide' | 'show', {recurseIntoArrays: false}>;
97
+
98
+ const userMaskSettings: UserMask = {
99
+ id: 'show',
100
+ name: {
101
+ firstname: 'show',
102
+ lastname: 'mask',
103
+ },
104
+ created: 'show',
105
+ active: 'show',
106
+ passwordHash: 'hide',
107
+ attributes: 'hide'
108
+ }
109
+ ```
110
+
111
+ @default true
112
+ */
113
+ readonly recurseIntoArrays?: boolean | undefined;
71
114
  };
@@ -98,13 +98,18 @@ export type SharedUnionFieldsDeep<Union, Options extends SharedUnionFieldsDeepOp
98
98
  Same as `SharedUnionFieldsDeep`, but accepts only `object`s and as inputs. Internal helper for `SharedUnionFieldsDeep`.
99
99
  */
100
100
  type SharedObjectUnionFieldsDeep<Union, Options extends SharedUnionFieldsDeepOptions> =
101
+ // `keyof Union` can extract the same key in union type, if there is no same key, return never.
101
102
  keyof Union extends infer Keys
102
103
  ? IsNever<Keys> extends false
103
104
  ? {
104
105
  [Key in keyof Union]:
105
106
  Union[Key] extends NonRecursiveType
106
107
  ? Union[Key]
107
- : SharedUnionFieldsDeep<Union[Key], Options>
108
+ // Remove `undefined` from the union to support optional
109
+ // fields, then recover `undefined` if union was already undefined.
110
+ : SharedUnionFieldsDeep<Exclude<Union[Key], undefined>, Options> | (
111
+ undefined extends Required<Union>[Key] ? undefined : never
112
+ )
108
113
  }
109
114
  : {}
110
115
  : Union;