type-fest 4.30.2 → 4.31.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/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "type-fest",
3
- "version": "4.30.2",
3
+ "version": "4.31.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
@@ -367,6 +367,7 @@ type ShouldBeNever = IfAny<'not any', 'not never', 'never'>;
367
367
  - `SetElement` - See [`IterableElement`](source/iterable-element.d.ts)
368
368
  - `SetEntry` - See [`IterableElement`](source/iterable-element.d.ts)
369
369
  - `SetValues` - See [`IterableElement`](source/iterable-element.d.ts)
370
+ - `PickByTypes` - See [`ConditionalPick`](source/conditional-pick.d.ts)
370
371
 
371
372
  ## Tips
372
373
 
@@ -1,5 +1,6 @@
1
1
  import type {Simplify} from '../simplify';
2
2
  import type {UnknownArray} from '../unknown-array';
3
+ import type {KeysOfUnion} from '../keys-of-union';
3
4
  import type {FilterDefinedKeys, FilterOptionalKeys} from './keys';
4
5
  import type {NonRecursiveType} from './type';
5
6
  import type {ToString} from './string';
@@ -80,3 +81,44 @@ export type UndefinedToOptional<T extends object> = Simplify<
80
81
  [Key in keyof Pick<T, FilterOptionalKeys<T>>]?: Exclude<T[Key], undefined>;
81
82
  }
82
83
  >;
84
+
85
+ /**
86
+ Works similar to the built-in `Pick` utility type, except for the following differences:
87
+ - Distributes over union types and allows picking keys from any member of the union type.
88
+ - Primitives types are returned as-is.
89
+ - Picks all keys if `Keys` is `any`.
90
+ - Doesn't pick `number` from a `string` index signature.
91
+
92
+ @example
93
+ ```
94
+ type ImageUpload = {
95
+ url: string;
96
+ size: number;
97
+ thumbnailUrl: string;
98
+ };
99
+
100
+ type VideoUpload = {
101
+ url: string;
102
+ duration: number;
103
+ encodingFormat: string;
104
+ };
105
+
106
+ // Distributes over union types and allows picking keys from any member of the union type
107
+ type MediaDisplay = HomomorphicPick<ImageUpload | VideoUpload, "url" | "size" | "duration">;
108
+ //=> {url: string; size: number} | {url: string; duration: number}
109
+
110
+ // Primitive types are returned as-is
111
+ type Primitive = HomomorphicPick<string | number, 'toUpperCase' | 'toString'>;
112
+ //=> string | number
113
+
114
+ // Picks all keys if `Keys` is `any`
115
+ type Any = HomomorphicPick<{a: 1; b: 2} | {c: 3}, any>;
116
+ //=> {a: 1; b: 2} | {c: 3}
117
+
118
+ // Doesn't pick `number` from a `string` index signature
119
+ type IndexSignature = HomomorphicPick<{[k: string]: unknown}, number>;
120
+ //=> {}
121
+ */
122
+ export type HomomorphicPick<T, Keys extends KeysOfUnion<T>> = {
123
+ [P in keyof T as Extract<P, Keys>]: T[P]
124
+ };
@@ -25,7 +25,7 @@ type Includes<Value extends readonly any[], Item> =
25
25
  @category Utilities
26
26
  */
27
27
  export type IsEqual<A, B> =
28
- (<G>() => G extends A ? 1 : 2) extends
29
- (<G>() => G extends B ? 1 : 2)
28
+ (<G>() => G extends A & G | G ? 1 : 2) extends
29
+ (<G>() => G extends B & G | G ? 1 : 2)
30
30
  ? true
31
31
  : false;
@@ -1,6 +1,16 @@
1
- import type {Except} from './except';
2
1
  import type {Simplify} from './simplify';
3
2
 
3
+ type SetFieldTypeOptions = {
4
+ /**
5
+ Preserve optional and readonly modifiers for properties being updated.
6
+
7
+ NOTE: Property modifiers will always be preserved for properties that are not being updated.
8
+
9
+ @default true
10
+ */
11
+ preservePropertyModifiers?: boolean;
12
+ };
13
+
4
14
  /**
5
15
  Create a type that changes the type of the given keys.
6
16
 
@@ -15,23 +25,33 @@ Use-cases:
15
25
  import type {SetFieldType} from 'type-fest';
16
26
 
17
27
  type MyModel = {
18
- id: number;
19
- createdAt: Date;
20
- updatedAt: Date;
28
+ readonly id: number;
29
+ readonly createdAt: Date;
30
+ updatedAt?: Date;
21
31
  };
22
32
 
23
33
  type MyModelApi = SetFieldType<MyModel, 'createdAt' | 'updatedAt', string>;
24
34
  // {
25
- // id: number;
26
- // createdAt: string;
27
- // updatedAt: string;
35
+ // readonly id: number;
36
+ // readonly createdAt: string;
37
+ // updatedAt?: string;
38
+ // }
39
+
40
+ // `preservePropertyModifiers` option can be set to `false` if you want to remove property modifiers for properties being updated
41
+ type MyModelApi = SetFieldType<MyModel, 'createdAt' | 'updatedAt', string, {preservePropertyModifiers: false}>;
42
+ // {
43
+ // readonly id: number;
44
+ // createdAt: string; // no longer readonly
45
+ // updatedAt: string; // no longer optional
28
46
  // }
29
47
  ```
30
48
 
31
49
  @category Object
32
50
  */
33
- export type SetFieldType<BaseType, Keys extends keyof BaseType, NewType> =
34
- Simplify<
35
- Except<BaseType, Keys> &
36
- Record<Keys, NewType>
37
- >;
51
+ export type SetFieldType<BaseType, Keys extends keyof BaseType, NewType, Options extends SetFieldTypeOptions = {preservePropertyModifiers: true}> =
52
+ Simplify<{
53
+ [P in keyof BaseType]: P extends Keys ? NewType : BaseType[P];
54
+ } & (
55
+ // `Record` is used to remove property modifiers
56
+ Options['preservePropertyModifiers'] extends false ? Record<Keys, NewType> : unknown
57
+ )>;
@@ -1,4 +1,6 @@
1
1
  import type {Except} from './except';
2
+ import type {HomomorphicPick} from './internal';
3
+ import type {KeysOfUnion} from './keys-of-union';
2
4
  import type {Simplify} from './simplify';
3
5
 
4
6
  /**
@@ -32,6 +34,6 @@ export type SetOptional<BaseType, Keys extends keyof BaseType> =
32
34
  // Pick just the keys that are readonly from the base type.
33
35
  Except<BaseType, Keys> &
34
36
  // Pick the keys that should be mutable from the base type and make them mutable.
35
- Partial<Except<BaseType, Exclude<keyof BaseType, Keys>>>
37
+ Partial<HomomorphicPick<BaseType, Keys & KeysOfUnion<BaseType>>>
36
38
  >
37
39
  : never;
@@ -1,4 +1,6 @@
1
1
  import type {Except} from './except';
2
+ import type {HomomorphicPick} from './internal';
3
+ import type {KeysOfUnion} from './keys-of-union';
2
4
  import type {Simplify} from './simplify';
3
5
 
4
6
  /**
@@ -33,6 +35,6 @@ export type SetReadonly<BaseType, Keys extends keyof BaseType> =
33
35
  BaseType extends unknown
34
36
  ? Simplify<
35
37
  Except<BaseType, Keys> &
36
- Readonly<Except<BaseType, Exclude<keyof BaseType, Keys>>>
38
+ Readonly<HomomorphicPick<BaseType, Keys & KeysOfUnion<BaseType>>>
37
39
  >
38
40
  : never;
@@ -1,4 +1,6 @@
1
1
  import type {Except} from './except';
2
+ import type {HomomorphicPick} from './internal';
3
+ import type {KeysOfUnion} from './keys-of-union';
2
4
  import type {Simplify} from './simplify';
3
5
 
4
6
  /**
@@ -35,6 +37,6 @@ export type SetRequired<BaseType, Keys extends keyof BaseType> =
35
37
  // Pick just the keys that are optional from the base type.
36
38
  Except<BaseType, Keys> &
37
39
  // Pick the keys that should be required from the base type and make them required.
38
- Required<Except<BaseType, Exclude<keyof BaseType, Keys>>>
40
+ Required<HomomorphicPick<BaseType, Keys & KeysOfUnion<BaseType>>>
39
41
  >
40
42
  : never;