type-fest 3.8.0 → 3.9.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.9.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
@@ -135,6 +135,7 @@ Click the type names for complete docs.
135
135
  - [`Merge`](source/merge.d.ts) - Merge two types into a new type. Keys of the second type overrides keys of the first type.
136
136
  - [`MergeDeep`](source/merge-deep.d.ts) - Merge two objects or two arrays/tuples recursively into a new type.
137
137
  - [`MergeExclusive`](source/merge-exclusive.d.ts) - Create a type that has mutually exclusive keys.
138
+ - [`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
139
  - [`RequireAtLeastOne`](source/require-at-least-one.d.ts) - Create a type that requires at least one of the given keys.
139
140
  - [`RequireExactlyOne`](source/require-exactly-one.d.ts) - Create a type that requires exactly a single key of the given keys and disallows more.
140
141
  - [`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,26 @@
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 TS2559: Type '{c: number}' has no properties in common with type 'Partial{a: unknown; b: unknown}>'.
19
+ ```
20
+
21
+ @category Object
22
+ */
23
+ export type OverrideProperties<
24
+ TOriginal,
25
+ TOverride extends Partial<{[key in keyof TOriginal]: unknown}>,
26
+ > = Merge<TOriginal, TOverride>;