type-fest 3.8.0 → 3.10.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
@@ -72,6 +72,7 @@ export type {StringKeyOf} from './source/string-key-of';
72
72
  export type {Exact} from './source/exact';
73
73
  export type {ReadonlyTuple} from './source/readonly-tuple';
74
74
  export type {OptionalKeysOf} from './source/optional-keys-of';
75
+ export type {OverrideProperties} from './source/override-properties';
75
76
  export type {HasOptionalKeys} from './source/has-optional-keys';
76
77
  export type {RequiredKeysOf} from './source/required-keys-of';
77
78
  export type {HasRequiredKeys} from './source/has-required-keys';
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "type-fest",
3
- "version": "3.8.0",
3
+ "version": "3.10.0",
4
4
  "description": "A collection of essential TypeScript types",
5
5
  "license": "(MIT OR CC0-1.0)",
6
6
  "repository": "sindresorhus/type-fest",
@@ -40,6 +40,9 @@
40
40
  "typescript": "^5.0.2",
41
41
  "xo": "^0.53.1"
42
42
  },
43
+ "peerDependencies": {
44
+ "typescript": ">=4.7.0"
45
+ },
43
46
  "xo": {
44
47
  "rules": {
45
48
  "@typescript-eslint/ban-ts-comment": "off",
package/readme.md CHANGED
@@ -37,37 +37,6 @@
37
37
  <sup>Add Single Sign-On (and more) in minutes instead of months.</sup>
38
38
  </div>
39
39
  </a>
40
- <br>
41
- <br>
42
- <br>
43
- <a href="https://www.useanvil.com/?utm_source=sindresorhus#gh-light-mode-only">
44
- <div>
45
- <img src="https://sindresorhus.com/assets/thanks/anvil-logo-light.svg" width="200" alt="Anvil">
46
- </div>
47
- <br>
48
- <b>Paperwork that makes the data work.</b>
49
- <div>
50
- <sub>
51
- Easy APIs for paperwork. PDF generation, e-signature and embeddable no-code webforms.
52
- <br>
53
- The easiest way to build paperwork automation into your product.
54
- </sub>
55
- </div>
56
- </a>
57
- <a href="https://www.useanvil.com/?utm_source=sindresorhus#gh-dark-mode-only">
58
- <div>
59
- <img src="https://sindresorhus.com/assets/thanks/anvil-logo-dark.svg" width="200" alt="Anvil">
60
- </div>
61
- <br>
62
- <b>Paperwork that makes the data work.</b>
63
- <div>
64
- <sub>
65
- Easy APIs for paperwork. PDF generation, e-signature and embeddable no-code webforms.
66
- <br>
67
- The easiest way to build paperwork automation into your product.
68
- </sub>
69
- </div>
70
- </a>
71
40
  </p>
72
41
  </div>
73
42
  <br>
@@ -135,6 +104,7 @@ Click the type names for complete docs.
135
104
  - [`Merge`](source/merge.d.ts) - Merge two types into a new type. Keys of the second type overrides keys of the first type.
136
105
  - [`MergeDeep`](source/merge-deep.d.ts) - Merge two objects or two arrays/tuples recursively into a new type.
137
106
  - [`MergeExclusive`](source/merge-exclusive.d.ts) - Create a type that has mutually exclusive keys.
107
+ - [`OverrideProperties`](source/override-properties.d.ts) - Override only existing properties of the given type. Similar to `Merge`, but enforces that the original type has the properties you want to override.
138
108
  - [`RequireAtLeastOne`](source/require-at-least-one.d.ts) - Create a type that requires at least one of the given keys.
139
109
  - [`RequireExactlyOne`](source/require-exactly-one.d.ts) - Create a type that requires exactly a single key of the given keys and disallows more.
140
110
  - [`RequireAllOrNone`](source/require-all-or-none.d.ts) - Create a type that requires all of the given keys or none of the given keys.
package/source/join.d.ts CHANGED
@@ -1,3 +1,13 @@
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
+
1
11
  /**
2
12
  Join an array of strings and/or numbers using the given string as a delimiter.
3
13
 
@@ -15,21 +25,44 @@ const path: Join<['foo', 'bar', 'baz'], '.'> = ['foo', 'bar', 'baz'].join('.');
15
25
 
16
26
  // Only number items; result is: '1.2.3'
17
27
  const path: Join<[1, 2, 3], '.'> = [1, 2, 3].join('.');
28
+
29
+ // Only bigint items; result is '1.2.3'
30
+ const path: Join<[1n, 2n, 3n], '.'> = [1n, 2n, 3n].join('.');
31
+
32
+ // Only boolean items; result is: 'true.false.true'
33
+ const path: Join<[true, false, true], '.'> = [true, false, true].join('.');
34
+
35
+ // Contains nullish items; result is: 'foo..baz..xyz'
36
+ const path: Join<['foo', undefined, 'baz', null, 'xyz'], '.'> = ['foo', undefined, 'baz', null, 'xyz'].join('.');
37
+
38
+ // Partial tuple shapes (rest param last); result is: `prefix.${string}`
39
+ const path: Join<['prefix', ...string[]], '.'> = ['prefix'].join('.');
40
+
41
+ // Partial tuple shapes (rest param first); result is: `${string}.suffix`
42
+ const path: Join<[...string[], 'suffix'], '.'> = ['suffix'].join('.');
43
+
44
+ // Tuples items with nullish unions; result is '.' | 'hello.' | '.world' | 'hello.world'
45
+ const path: Join<['hello' | undefined, 'world' | null], '.'> = ['hello', 'world'].join('.');
18
46
  ```
19
47
 
20
48
  @category Array
21
49
  @category Template literal
22
50
  */
23
51
  export type Join<
24
- Strings extends ReadonlyArray<string | number>,
52
+ Items extends readonly JoinableItem[],
25
53
  Delimiter extends string,
26
- > = Strings extends []
54
+ > = Items extends []
27
55
  ? ''
28
- : Strings extends readonly [string | number]
29
- ? `${Strings[0]}`
30
- : Strings extends readonly [
31
- string | number,
32
- ...infer Rest extends ReadonlyArray<string | number>,
56
+ : Items extends readonly [JoinableItem?]
57
+ ? `${NullishCoalesce<Items[0], ''>}`
58
+ : Items extends readonly [
59
+ infer First extends JoinableItem,
60
+ ...infer Tail extends readonly JoinableItem[],
33
61
  ]
34
- ? `${Strings[0]}${Delimiter}${Join<Rest, Delimiter>}`
35
- : string;
62
+ ? `${NullishCoalesce<First, ''>}${Delimiter}${Join<Tail, Delimiter>}`
63
+ : Items extends readonly [
64
+ ...infer Head extends readonly JoinableItem[],
65
+ infer Last extends JoinableItem,
66
+ ]
67
+ ? `${Join<Head, Delimiter>}${Delimiter}${NullishCoalesce<Last, ''>}`
68
+ : string;
@@ -0,0 +1,29 @@
1
+ import type {Merge} from './merge';
2
+
3
+ /**
4
+ Override existing properties of the given type. Similar to `Merge`, but enforces that the original type has the properties you want to override.
5
+
6
+ This is useful when you want to override existing properties with a different type and make sure that these properties really exist in the original.
7
+
8
+ @example
9
+ ```
10
+ type Foo = {
11
+ a: string
12
+ b: string
13
+ }
14
+ type Bar = OverrideProperties<Foo, {b: number}>
15
+ //=> {a: string, b: number}
16
+
17
+ type Baz = OverrideProperties<Foo, {c: number}>
18
+ // Error, type '{ c: number; }' does not satisfy the constraint '{ c: never; }'
19
+
20
+ type Fizz = OverrideProperties<Foo, {b: number; c: number}>
21
+ // Error, type '{ b: number; c: number; }' does not satisfy the constraint '{ b: number; c: never; }'
22
+ ```
23
+
24
+ @category Object
25
+ */
26
+ export type OverrideProperties<
27
+ TOriginal,
28
+ TOverride extends {[Key in keyof TOverride]: Key extends keyof TOriginal ? TOverride[Key] : never},
29
+ > = Merge<TOriginal, TOverride>;
@@ -28,8 +28,7 @@ type SomeRequired = SetRequired<Foo, 'b' | 'c'>;
28
28
  */
29
29
  export type SetRequired<BaseType, Keys extends keyof BaseType> =
30
30
  Simplify<
31
- // Pick just the keys that are optional from the base type.
32
- Except<BaseType, Keys> &
31
+ BaseType &
33
32
  // Pick the keys that should be required from the base type and make them required.
34
33
  Required<Pick<BaseType, Keys>>
35
34
  >;