type-fest 5.5.0 → 5.6.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 (82) hide show
  1. package/index.d.ts +3 -0
  2. package/package.json +6 -4
  3. package/readme.md +70 -55
  4. package/source/absolute.d.ts +52 -0
  5. package/source/all-union-fields.d.ts +18 -18
  6. package/source/and.d.ts +1 -1
  7. package/source/array-splice.d.ts +24 -24
  8. package/source/camel-case.d.ts +38 -5
  9. package/source/camel-cased-properties-deep.d.ts +11 -4
  10. package/source/camel-cased-properties.d.ts +5 -1
  11. package/source/delimiter-case.d.ts +1 -0
  12. package/source/delimiter-cased-properties-deep.d.ts +8 -1
  13. package/source/delimiter-cased-properties.d.ts +5 -1
  14. package/source/empty-object.d.ts +1 -1
  15. package/source/entries.d.ts +1 -1
  16. package/source/entry.d.ts +1 -1
  17. package/source/get.d.ts +1 -1
  18. package/source/greater-than.d.ts +3 -2
  19. package/source/has-optional-keys.d.ts +1 -1
  20. package/source/has-readonly-keys.d.ts +1 -1
  21. package/source/has-required-keys.d.ts +1 -1
  22. package/source/has-writable-keys.d.ts +1 -1
  23. package/source/int-closed-range.d.ts +1 -3
  24. package/source/int-range.d.ts +3 -5
  25. package/source/internal/array.d.ts +7 -7
  26. package/source/internal/keys.d.ts +9 -9
  27. package/source/internal/numeric.d.ts +13 -23
  28. package/source/internal/tuple.d.ts +2 -2
  29. package/source/is-integer.d.ts +8 -8
  30. package/source/is-literal.d.ts +5 -5
  31. package/source/is-union.d.ts +12 -12
  32. package/source/iterable-element.d.ts +5 -5
  33. package/source/jsonify.d.ts +4 -4
  34. package/source/kebab-case.d.ts +1 -0
  35. package/source/kebab-cased-properties-deep.d.ts +7 -0
  36. package/source/kebab-cased-properties.d.ts +5 -1
  37. package/source/keys-of-union.d.ts +2 -2
  38. package/source/less-than-or-equal.d.ts +1 -1
  39. package/source/literal-to-primitive.d.ts +1 -1
  40. package/source/literal-union.d.ts +1 -1
  41. package/source/merge-exclusive.d.ts +3 -3
  42. package/source/multidimensional-array.d.ts +1 -1
  43. package/source/multidimensional-readonly-array.d.ts +1 -1
  44. package/source/non-nullable-deep.d.ts +102 -0
  45. package/source/numeric.d.ts +3 -3
  46. package/source/omit-deep.d.ts +22 -22
  47. package/source/or.d.ts +1 -1
  48. package/source/package-json.d.ts +7 -7
  49. package/source/partial-deep.d.ts +3 -1
  50. package/source/pascal-case.d.ts +1 -0
  51. package/source/pascal-cased-properties-deep.d.ts +7 -0
  52. package/source/pascal-cased-properties.d.ts +5 -1
  53. package/source/pick-deep.d.ts +2 -0
  54. package/source/readonly-deep.d.ts +5 -3
  55. package/source/remove-prefix.d.ts +15 -15
  56. package/source/replace.d.ts +2 -2
  57. package/source/require-all-or-none.d.ts +1 -1
  58. package/source/require-at-least-one.d.ts +5 -7
  59. package/source/require-exactly-one.d.ts +3 -3
  60. package/source/require-one-or-none.d.ts +1 -1
  61. package/source/required-deep.d.ts +3 -1
  62. package/source/screaming-snake-case.d.ts +1 -0
  63. package/source/set-non-nullable-deep.d.ts +6 -3
  64. package/source/set-non-nullable.d.ts +1 -1
  65. package/source/set-optional.d.ts +5 -5
  66. package/source/set-readonly.d.ts +3 -3
  67. package/source/set-required-deep.d.ts +1 -1
  68. package/source/set-required.d.ts +3 -3
  69. package/source/shared-union-fields.d.ts +9 -9
  70. package/source/snake-case.d.ts +1 -0
  71. package/source/snake-cased-properties-deep.d.ts +7 -0
  72. package/source/snake-cased-properties.d.ts +5 -1
  73. package/source/subtract.d.ts +4 -3
  74. package/source/sum.d.ts +5 -4
  75. package/source/tagged.d.ts +3 -5
  76. package/source/tsconfig-json.d.ts +39 -7
  77. package/source/union-length.d.ts +27 -0
  78. package/source/union-to-intersection.d.ts +1 -1
  79. package/source/union-to-tuple.d.ts +8 -4
  80. package/source/words.d.ts +30 -4
  81. package/source/writable.d.ts +14 -14
  82. package/source/xor.d.ts +1 -1
@@ -121,9 +121,9 @@ declare function setPercentage<T extends number>(length: Float<T>): void;
121
121
  @category Numeric
122
122
  */
123
123
  export type Float<T> =
124
- T extends unknown // To distributive type
125
- ? IsFloat<T> extends true ? T : never
126
- : never; // Never happens
124
+ T extends unknown // To distributive type
125
+ ? IsFloat<T> extends true ? T : never
126
+ : never; // Never happens
127
127
 
128
128
  /**
129
129
  A negative (`-∞ < x < 0`) `number` that is not an integer.
@@ -17,7 +17,7 @@ It supports removing specific items from an array, replacing each removed item w
17
17
 
18
18
  Use-case: Remove unneeded parts of complex objects.
19
19
 
20
- Use [`Omit`](https://www.typescriptlang.org/docs/handbook/utility-types.html#omittype-keys) if you only need one level deep.
20
+ Use [`Omit<T>`](https://www.typescriptlang.org/docs/handbook/utility-types.html#omittype-keys) if you only need one level deep.
21
21
 
22
22
  @example
23
23
  ```
@@ -93,34 +93,34 @@ type OmitDeepHelper<T, PathTuple extends UnknownArray> =
93
93
  Omit one path from the given object/array.
94
94
  */
95
95
  type OmitDeepWithOnePath<T, Path extends string | number> =
96
- T extends NonRecursiveType
97
- ? T
98
- : T extends UnknownArray ? SetArrayAccess<OmitDeepArrayWithOnePath<T, Path>, IsArrayReadonly<T>>
99
- : T extends object ? OmitDeepObjectWithOnePath<T, Path>
100
- : T;
96
+ T extends NonRecursiveType
97
+ ? T
98
+ : T extends UnknownArray ? SetArrayAccess<OmitDeepArrayWithOnePath<T, Path>, IsArrayReadonly<T>>
99
+ : T extends object ? OmitDeepObjectWithOnePath<T, Path>
100
+ : T;
101
101
 
102
102
  /**
103
103
  Omit one path from the given object.
104
104
  */
105
105
  type OmitDeepObjectWithOnePath<ObjectT extends object, P extends string | number> =
106
- P extends `${infer RecordKeyInPath}.${infer SubPath}`
107
- ? {
108
- [Key in keyof ObjectT]:
109
- IsEqual<RecordKeyInPath, ToString<Key>> extends true
110
- ? ExactKey<ObjectT, Key> extends infer RealKey
111
- ? RealKey extends keyof ObjectT
112
- ? OmitDeepWithOnePath<ObjectT[RealKey], SubPath>
106
+ P extends `${infer RecordKeyInPath}.${infer SubPath}`
107
+ ? {
108
+ [Key in keyof ObjectT]:
109
+ IsEqual<RecordKeyInPath, ToString<Key>> extends true
110
+ ? ExactKey<ObjectT, Key> extends infer RealKey
111
+ ? RealKey extends keyof ObjectT
112
+ ? OmitDeepWithOnePath<ObjectT[RealKey], SubPath>
113
+ : ObjectT[Key]
113
114
  : ObjectT[Key]
114
115
  : ObjectT[Key]
115
- : ObjectT[Key]
116
- }
117
- : ExactKey<ObjectT, P> extends infer Key
118
- ? IsNever<Key> extends true
119
- ? ObjectT
120
- : Key extends PropertyKey
121
- ? Omit<ObjectT, Key>
122
- : ObjectT
123
- : ObjectT;
116
+ }
117
+ : ExactKey<ObjectT, P> extends infer Key
118
+ ? IsNever<Key> extends true
119
+ ? ObjectT
120
+ : Key extends PropertyKey
121
+ ? Omit<ObjectT, Key>
122
+ : ObjectT
123
+ : ObjectT;
124
124
 
125
125
  /**
126
126
  Omit one path from from the given array.
package/source/or.d.ts CHANGED
@@ -1,7 +1,7 @@
1
1
  import type {OrAll} from './or-all.d.ts';
2
2
 
3
3
  /**
4
- Returns a boolean for whether either of two given types is true.
4
+ Returns a boolean for whether either of two given types is `true`.
5
5
 
6
6
  Use-case: Constructing complex conditional types where at least one condition must be satisfied.
7
7
 
@@ -699,12 +699,12 @@ Type for [npm's `package.json` file](https://docs.npmjs.com/creating-a-package-j
699
699
  @category File
700
700
  */
701
701
  export type PackageJson =
702
- JsonObject &
703
- PackageJson.NodeJsStandard &
704
- PackageJson.PackageJsonStandard &
705
- PackageJson.NonStandardEntryPoints &
706
- PackageJson.TypeScriptConfiguration &
707
- PackageJson.YarnConfiguration &
708
- PackageJson.JSPMConfiguration;
702
+ JsonObject
703
+ & PackageJson.NodeJsStandard
704
+ & PackageJson.PackageJsonStandard
705
+ & PackageJson.NonStandardEntryPoints
706
+ & PackageJson.TypeScriptConfiguration
707
+ & PackageJson.YarnConfiguration
708
+ & PackageJson.JSPMConfiguration;
709
709
 
710
710
  export {};
@@ -44,12 +44,14 @@ type DefaultPartialDeepOptions = {
44
44
  };
45
45
 
46
46
  /**
47
- Create a type from another type with all keys and nested keys set to optional.
47
+ Create a deeply optional version of another type.
48
48
 
49
49
  Use-cases:
50
50
  - Merging a default settings/config object with another object, the second object would be a deep partial of the default object.
51
51
  - Mocking and testing complex entities, where populating an entire object with its keys would be redundant in terms of the mock or test.
52
52
 
53
+ Use [`Partial<T>`](https://www.typescriptlang.org/docs/handbook/utility-types.html#partialtype) if you only need one level deep.
54
+
53
55
  @example
54
56
  ```
55
57
  import type {PartialDeep} from 'type-fest';
@@ -12,6 +12,7 @@ import type {PascalCase} from 'type-fest';
12
12
 
13
13
  const someVariable: PascalCase<'foo-bar'> = 'FooBar';
14
14
  const preserveConsecutiveUppercase: PascalCase<'foo-BAR-baz', {preserveConsecutiveUppercase: true}> = 'FooBARBaz';
15
+ const splitOnPunctuation: PascalCase<'foo-bar>>baz', {splitOnPunctuation: true}> = 'FooBarBaz';
15
16
 
16
17
  // Advanced
17
18
 
@@ -48,6 +48,13 @@ const preserveConsecutiveUppercase: PascalCasedPropertiesDeep<{fooBAR: {fooBARBi
48
48
  }],
49
49
  },
50
50
  };
51
+
52
+ const splitOnPunctuation: PascalCasedPropertiesDeep<{'user@info': {'user::id': number; 'user::name': string}}, {splitOnPunctuation: true}> = {
53
+ UserInfo: {
54
+ UserId: 1,
55
+ UserName: 'Tom',
56
+ },
57
+ };
51
58
  ```
52
59
 
53
60
  @category Change case
@@ -3,7 +3,7 @@ import type {ApplyDefaultOptions} from './internal/index.d.ts';
3
3
  import type {PascalCase} from './pascal-case.d.ts';
4
4
 
5
5
  /**
6
- Convert object properties to pascal case but not recursively.
6
+ Convert top-level object properties to pascal case.
7
7
 
8
8
  This can be useful when, for example, converting some API types from a different style.
9
9
 
@@ -27,6 +27,10 @@ const result: PascalCasedProperties<User> = {
27
27
  const preserveConsecutiveUppercase: PascalCasedProperties<{fooBAR: string}, {preserveConsecutiveUppercase: true}> = {
28
28
  FooBAR: 'string',
29
29
  };
30
+
31
+ const splitOnPunctuation: PascalCasedProperties<{'foo::bar': string}, {splitOnPunctuation: true}> = {
32
+ FooBar: 'string',
33
+ };
30
34
  ```
31
35
 
32
36
  @category Change case
@@ -14,6 +14,8 @@ It supports recursing into arrays.
14
14
 
15
15
  Use-case: Distill complex objects down to the components you need to target.
16
16
 
17
+ Use [`Pick<T>`](https://www.typescriptlang.org/docs/handbook/utility-types.html#picktype-keys) if you only need one level deep.
18
+
17
19
  @example
18
20
  ```
19
21
  import type {PickDeep, PartialDeep} from 'type-fest';
@@ -1,12 +1,14 @@
1
1
  import type {BuiltIns, HasMultipleCallSignatures} from './internal/index.d.ts';
2
2
 
3
3
  /**
4
- Convert `object`s, `Map`s, `Set`s, and `Array`s and all of their keys/elements into immutable structures recursively.
4
+ Create a deeply immutable version of another type.
5
5
 
6
6
  This is useful when a deeply nested structure needs to be exposed as completely immutable, for example, an imported JSON module or when receiving an API response that is passed around.
7
7
 
8
8
  Please upvote [this issue](https://github.com/microsoft/TypeScript/issues/13923) if you want to have this type as a built-in in TypeScript.
9
9
 
10
+ Use [`Readonly<T>`](https://www.typescriptlang.org/docs/handbook/utility-types.html#readonlytype) if you only need one level deep.
11
+
10
12
  @example
11
13
  ```
12
14
  import type {ReadonlyDeep} from 'type-fest';
@@ -83,8 +85,8 @@ export type ReadonlyDeep<T> = T extends BuiltIns
83
85
  ? ReadonlyMapDeep<KeyType, ValueType>
84
86
  : T extends Readonly<ReadonlySet<infer ItemType>>
85
87
  ? ReadonlySetDeep<ItemType>
86
- : // Identify tuples to avoid converting them to arrays inadvertently; special case `readonly [...never[]]`, as it emerges undesirably from recursive invocations of ReadonlyDeep below.
87
- T extends readonly [] | readonly [...never[]]
88
+ // Identify tuples to avoid converting them to arrays inadvertently; special case `readonly [...never[]]`, as it emerges undesirably from recursive invocations of ReadonlyDeep below.
89
+ : T extends readonly [] | readonly [...never[]]
88
90
  ? readonly []
89
91
  : T extends readonly [infer U, ...infer V]
90
92
  ? readonly [ReadonlyDeep<U>, ...ReadonlyDeep<V>]
@@ -110,23 +110,23 @@ type D = RemovePrefix<`handle${Capitalize<string>}`, 'handle'>;
110
110
  @category Template literal
111
111
  */
112
112
  export type RemovePrefix<S extends string, Prefix extends string, Options extends RemovePrefixOptions = {}> =
113
- IfNotAnyOrNever<
114
- S,
115
113
  IfNotAnyOrNever<
116
- Prefix,
117
- _RemovePrefix<S, Prefix, ApplyDefaultOptions<RemovePrefixOptions, DefaultRemovePrefixOptions, Options>>,
118
- string,
119
- S
120
- >
121
- >;
114
+ S,
115
+ IfNotAnyOrNever<
116
+ Prefix,
117
+ _RemovePrefix<S, Prefix, ApplyDefaultOptions<RemovePrefixOptions, DefaultRemovePrefixOptions, Options>>,
118
+ string,
119
+ S
120
+ >
121
+ >;
122
122
 
123
123
  type _RemovePrefix<S extends string, Prefix extends string, Options extends Required<RemovePrefixOptions>> =
124
- Prefix extends string // For distributing `Prefix`
125
- ? S extends `${Prefix}${infer Rest}`
126
- ? Or<IsStringLiteral<Prefix>, Not<Options['strict']>> extends true
127
- ? Rest
128
- : string // Fallback to `string` when `Prefix` is non-literal and `strict` is disabled
129
- : S // Return back `S` when `Prefix` is not present at the start of `S`
130
- : never;
124
+ Prefix extends string // For distributing `Prefix`
125
+ ? S extends `${Prefix}${infer Rest}`
126
+ ? Or<IsStringLiteral<Prefix>, Not<Options['strict']>> extends true
127
+ ? Rest
128
+ : string // Fallback to `string` when `Prefix` is non-literal and `strict` is disabled
129
+ : S // Return back `S` when `Prefix` is not present at the start of `S`
130
+ : never;
131
131
 
132
132
  export {};
@@ -27,7 +27,7 @@ declare function replace<
27
27
  >(
28
28
  input: Input,
29
29
  search: Search,
30
- replacement: Replacement
30
+ replacement: Replacement,
31
31
  ): Replace<Input, Search, Replacement>;
32
32
 
33
33
  declare function replaceAll<
@@ -37,7 +37,7 @@ declare function replaceAll<
37
37
  >(
38
38
  input: Input,
39
39
  search: Search,
40
- replacement: Replacement
40
+ replacement: Replacement,
41
41
  ): Replace<Input, Search, Replacement, {all: true}>;
42
42
 
43
43
  // The return type is the exact string literal, not just `string`.
@@ -9,7 +9,7 @@ Requires all of the keys in the given object.
9
9
  type RequireAll<ObjectType, KeysType extends keyof ObjectType> = Required<Pick<ObjectType, KeysType>>;
10
10
 
11
11
  /**
12
- Create a type that requires all of the given keys or none of the given keys. The remaining keys are kept as is.
12
+ Create a type that requires all of the given keys or none of the given keys, while keeping the remaining keys as is.
13
13
 
14
14
  Use-cases:
15
15
  - Creating interfaces for components with mutually-inclusive keys.
@@ -5,7 +5,7 @@ import type {IsAny} from './is-any.d.ts';
5
5
  import type {IsNever} from './is-never.d.ts';
6
6
 
7
7
  /**
8
- Create a type that requires at least one of the given keys. The remaining keys are kept as is.
8
+ Create a type that requires at least one of the given keys, while keeping the remaining keys as is.
9
9
 
10
10
  @example
11
11
  ```
@@ -40,11 +40,9 @@ type _RequireAtLeastOne<
40
40
  KeysType extends keyof ObjectType,
41
41
  > = {
42
42
  // For each `Key` in `KeysType` make a mapped type:
43
- [Key in KeysType]-?: Required<Pick<ObjectType, Key>> & // 1. Make `Key`'s type required
44
- // 2. Make all other keys in `KeysType` optional
45
- Partial<Pick<ObjectType, Exclude<KeysType, Key>>>;
46
- }[KeysType] &
47
- // 3. Add the remaining keys not in `KeysType`
48
- Except<ObjectType, KeysType>;
43
+ [Key in KeysType]-?: Required<Pick<ObjectType, Key>> // 1. Make `Key`'s type required
44
+ & Partial<Pick<ObjectType, Exclude<KeysType, Key>>>; // 2. Make all other keys in `KeysType` optional
45
+ }[KeysType]
46
+ & Except<ObjectType, KeysType>; // 3. Add the remaining keys not in `KeysType`
49
47
 
50
48
  export {};
@@ -4,7 +4,7 @@ import type {IsAny} from './is-any.d.ts';
4
4
  import type {IsNever} from './is-never.d.ts';
5
5
 
6
6
  /**
7
- Create a type that requires exactly one of the given keys and disallows more. The remaining keys are kept as is.
7
+ Create a type that requires exactly one of the given keys and disallows more, while keeping the remaining keys as is.
8
8
 
9
9
  Use-cases:
10
10
  - Creating interfaces for components that only need one of the keys to display properly.
@@ -41,8 +41,8 @@ export type RequireExactlyOne<ObjectType, KeysType extends keyof ObjectType = ke
41
41
 
42
42
  type _RequireExactlyOne<ObjectType, KeysType extends keyof ObjectType> =
43
43
  {[Key in KeysType]: (
44
- Required<Pick<ObjectType, Key>> &
45
- Partial<Record<Exclude<KeysType, Key>, never>>
44
+ Required<Pick<ObjectType, Key>>
45
+ & Partial<Record<Exclude<KeysType, Key>, never>>
46
46
  )}[KeysType] & Omit<ObjectType, KeysType>;
47
47
 
48
48
  export {};
@@ -5,7 +5,7 @@ import type {IsAny} from './is-any.d.ts';
5
5
  import type {IsNever} from './is-never.d.ts';
6
6
 
7
7
  /**
8
- Create a type that requires exactly one of the given keys and disallows more, or none of the given keys. The remaining keys are kept as is.
8
+ Create a type that requires exactly one of the given keys or none of the given keys, while keeping the remaining keys as is.
9
9
 
10
10
  @example
11
11
  ```
@@ -3,12 +3,14 @@ import type {IsNever} from './is-never.d.ts';
3
3
  import type {Simplify} from './simplify.d.ts';
4
4
 
5
5
  /**
6
- Create a type from another type with all keys and nested keys set to required.
6
+ Create a deeply required version of another type.
7
7
 
8
8
  Use-cases:
9
9
  - Creating optional configuration interfaces where the underlying implementation still requires all options to be fully specified.
10
10
  - Modeling the resulting type after a deep merge with a set of defaults.
11
11
 
12
+ Use [`Required<T>`](https://www.typescriptlang.org/docs/handbook/utility-types.html#requiredtype) if you only need one level deep.
13
+
12
14
  @example
13
15
  ```
14
16
  import type {RequiredDeep} from 'type-fest';
@@ -14,6 +14,7 @@ import type {ScreamingSnakeCase} from 'type-fest';
14
14
 
15
15
  const someVariable: ScreamingSnakeCase<'fooBar'> = 'FOO_BAR';
16
16
  const someVariableNoSplitOnNumbers: ScreamingSnakeCase<'p2pNetwork', {splitOnNumbers: false}> = 'P2P_NETWORK';
17
+ const someVariableWithPunctuation: ScreamingSnakeCase<'div.card::after', {splitOnPunctuation: true}> = 'DIV_CARD_AFTER';
17
18
 
18
19
  ```
19
20
 
@@ -1,4 +1,6 @@
1
1
  import type {NonRecursiveType, StringToNumber} from './internal/index.d.ts';
2
+ import type {IsAny} from './is-any.d.ts';
3
+ import type {NonNullableDeep} from './non-nullable-deep.d.ts';
2
4
  import type {Paths} from './paths.d.ts';
3
5
  import type {SetNonNullable} from './set-non-nullable.d.ts';
4
6
  import type {Simplify} from './simplify.d.ts';
@@ -8,7 +10,7 @@ import type {UnknownArray} from './unknown-array.d.ts';
8
10
  /**
9
11
  Create a type that makes the specified keys non-nullable (removes `null` and `undefined`), supports deeply nested key paths, and leaves all other keys unchanged.
10
12
 
11
- NOTE: Optional modifiers (`?`) are not removed from properties. For example, `SetNonNullableDeep<{foo?: string | null | undefined}, 'foo'>` will result in `{foo?: string}`.
13
+ NOTE: Optional modifiers (`?`) are not removed from properties. For example, `SetNonNullableDeep<{foo?: string | null | undefined}, 'foo'>` will result in `{foo?: string}`. To remove both optional modifiers and nullables, use {@link SetRequiredDeep} in conjunction with this type.
12
14
 
13
15
  @example
14
16
  ```
@@ -55,8 +57,9 @@ type ArrayExample2 = SetNonNullableDeep<{a: [(number | null)?, (number | null)?]
55
57
 
56
58
  @category Object
57
59
  */
58
- export type SetNonNullableDeep<BaseType, KeyPaths extends Paths<BaseType>> =
59
- SetNonNullableDeepHelper<BaseType, UnionToTuple<KeyPaths>>;
60
+ export type SetNonNullableDeep<BaseType, KeyPaths extends Paths<BaseType>> = IsAny<KeyPaths> extends true
61
+ ? NonNullableDeep<BaseType>
62
+ : SetNonNullableDeepHelper<BaseType, UnionToTuple<KeyPaths>>;
60
63
 
61
64
  /**
62
65
  Internal helper for {@link SetNonNullableDeep}.
@@ -1,5 +1,5 @@
1
1
  /**
2
- Create a type that makes the given keys non-nullable, where the remaining keys are kept as is.
2
+ Create a type that makes the given keys non-nullable, while keeping the remaining keys as is.
3
3
 
4
4
  If no keys are given, all keys will be made non-nullable.
5
5
 
@@ -3,7 +3,7 @@ import type {HomomorphicPick} from './internal/index.d.ts';
3
3
  import type {Simplify} from './simplify.d.ts';
4
4
 
5
5
  /**
6
- Create a type that makes the given keys optional. The remaining keys are kept as is. The sister of the `SetRequired` type.
6
+ Create a type that makes the given keys optional, while keeping the remaining keys as is.
7
7
 
8
8
  Use-case: You want to define a single model where the only thing that changes is whether or not some of the keys are optional.
9
9
 
@@ -32,10 +32,10 @@ export type SetOptional<BaseType, Keys extends keyof BaseType> =
32
32
  type _SetOptional<BaseType, Keys extends keyof BaseType> =
33
33
  BaseType extends unknown // To distribute `BaseType` when it's a union type.
34
34
  ? Simplify<
35
- // Pick just the keys that are readonly from the base type.
36
- Except<BaseType, Keys> &
37
- // Pick the keys that should be mutable from the base type and make them mutable.
38
- Partial<HomomorphicPick<BaseType, Keys>>
35
+ // Pick just the keys that are readonly from the base type.
36
+ Except<BaseType, Keys>
37
+ // Pick the keys that should be mutable from the base type and make them mutable.
38
+ & Partial<HomomorphicPick<BaseType, Keys>>
39
39
  >
40
40
  : never;
41
41
 
@@ -3,7 +3,7 @@ import type {HomomorphicPick} from './internal/index.d.ts';
3
3
  import type {Simplify} from './simplify.d.ts';
4
4
 
5
5
  /**
6
- Create a type that makes the given keys readonly. The remaining keys are kept as is.
6
+ Create a type that makes the given keys readonly, while keeping the remaining keys as is.
7
7
 
8
8
  Use-case: You want to define a single model where the only thing that changes is whether or not some of the keys are readonly.
9
9
 
@@ -32,8 +32,8 @@ export type SetReadonly<BaseType, Keys extends keyof BaseType> =
32
32
  export type _SetReadonly<BaseType, Keys extends keyof BaseType> =
33
33
  BaseType extends unknown // To distribute `BaseType` when it's a union type.
34
34
  ? Simplify<
35
- Except<BaseType, Keys> &
36
- Readonly<HomomorphicPick<BaseType, Keys>>
35
+ Except<BaseType, Keys>
36
+ & Readonly<HomomorphicPick<BaseType, Keys>>
37
37
  >
38
38
  : never;
39
39
 
@@ -8,7 +8,7 @@ import type {RequiredDeep} from './required-deep.d.ts';
8
8
  import type {UnknownArray} from './unknown-array.d.ts';
9
9
 
10
10
  /**
11
- Create a type that makes the given keys required. You can specify deeply nested key paths. The remaining keys are kept as is.
11
+ Create a type that makes the given keys required, with support for deeply nested key paths, while keeping the remaining keys as is.
12
12
 
13
13
  Use-case: Selectively make nested properties required in complex types like models.
14
14
 
@@ -6,7 +6,7 @@ import type {Simplify} from './simplify.d.ts';
6
6
  import type {UnknownArray} from './unknown-array.d.ts';
7
7
 
8
8
  /**
9
- Create a type that makes the given keys required. The remaining keys are kept as is. The sister of the `SetOptional` type.
9
+ Create a type that makes the given keys required, while keeping the remaining keys as is.
10
10
 
11
11
  Use-case: You want to define a single model where the only thing that changes is whether or not some of the keys are required.
12
12
 
@@ -43,9 +43,9 @@ type _SetRequired<BaseType, Keys extends keyof BaseType> =
43
43
  : never
44
44
  : Simplify<
45
45
  // Pick just the keys that are optional from the base type.
46
- Except<BaseType, Keys> &
46
+ Except<BaseType, Keys>
47
47
  // Pick the keys that should be required from the base type and make them required.
48
- Required<HomomorphicPick<BaseType, Keys>>
48
+ & Required<HomomorphicPick<BaseType, Keys>>
49
49
  >;
50
50
 
51
51
  /**
@@ -66,14 +66,14 @@ function displayPetInfoWithSharedUnionFields(petInfo: SharedUnionFields<Cat | Do
66
66
  @category Union
67
67
  */
68
68
  export type SharedUnionFields<Union> =
69
- Extract<Union, NonRecursiveType | ReadonlyMap<unknown, unknown> | ReadonlySet<unknown> | UnknownArray> extends infer SkippedMembers
70
- ? Exclude<Union, SkippedMembers> extends infer RelevantMembers
71
- ?
72
- | SkippedMembers
73
- | (IsNever<RelevantMembers> extends true
74
- ? never
75
- : Simplify<Pick<RelevantMembers, keyof RelevantMembers>>)
76
- : never
77
- : never;
69
+ Extract<Union, NonRecursiveType | ReadonlyMap<unknown, unknown> | ReadonlySet<unknown> | UnknownArray> extends infer SkippedMembers
70
+ ? Exclude<Union, SkippedMembers> extends infer RelevantMembers
71
+ ? // eslint-disable-line @stylistic/operator-linebreak
72
+ | SkippedMembers
73
+ | (IsNever<RelevantMembers> extends true
74
+ ? never
75
+ : Simplify<Pick<RelevantMembers, keyof RelevantMembers>>)
76
+ : never
77
+ : never;
78
78
 
79
79
  export {};
@@ -16,6 +16,7 @@ import type {SnakeCase} from 'type-fest';
16
16
  const someVariable: SnakeCase<'fooBar'> = 'foo_bar';
17
17
  const noSplitOnNumbers: SnakeCase<'p2pNetwork'> = 'p2p_network';
18
18
  const splitOnNumbers: SnakeCase<'p2pNetwork', {splitOnNumbers: true}> = 'p_2_p_network';
19
+ const splitOnPunctuation: SnakeCase<'div.card::after', {splitOnPunctuation: true}> = 'div_card_after';
19
20
 
20
21
  // Advanced
21
22
 
@@ -51,6 +51,13 @@ const splitOnNumbers: SnakeCasedPropertiesDeep<{line1: {line2: [{line3: string}]
51
51
  ],
52
52
  },
53
53
  };
54
+
55
+ const splitOnPunctuation: SnakeCasedPropertiesDeep<{'user@info': {'user::id': number; 'user::name': string}}, {splitOnPunctuation: true}> = {
56
+ 'user_info': {
57
+ 'user_id': 1,
58
+ 'user_name': 'Tom',
59
+ },
60
+ };
54
61
  ```
55
62
 
56
63
  @category Change case
@@ -4,7 +4,7 @@ import type {ApplyDefaultOptions} from './internal/index.d.ts';
4
4
  import type {WordsOptions} from './words.d.ts';
5
5
 
6
6
  /**
7
- Convert object properties to snake case but not recursively.
7
+ Convert top-level object properties to snake case.
8
8
 
9
9
  This can be useful when, for example, converting some API types from a different style.
10
10
 
@@ -28,6 +28,10 @@ const result: SnakeCasedProperties<User> = {
28
28
  const splitOnNumbers: SnakeCasedProperties<{line1: string}, {splitOnNumbers: true}> = {
29
29
  'line_1': 'string',
30
30
  };
31
+
32
+ const splitOnPunctuation: SnakeCasedProperties<{'foo::bar': string}, {splitOnPunctuation: true}> = {
33
+ 'foo_bar': 'string',
34
+ };
31
35
  ```
32
36
 
33
37
  @category Change case
@@ -1,7 +1,8 @@
1
- import type {NumberAbsolute, ReverseSign} from './internal/index.d.ts';
1
+ import type {ReverseSign} from './internal/index.d.ts';
2
2
  import type {PositiveInfinity, NegativeInfinity, IsNegative} from './numeric.d.ts';
3
3
  import type {LessThan} from './less-than.d.ts';
4
4
  import type {TupleOf} from './tuple-of.d.ts';
5
+ import type {Absolute} from './absolute.d.ts';
5
6
 
6
7
  /**
7
8
  Returns the difference between two numbers.
@@ -59,9 +60,9 @@ type SubtractPostChecks<A extends number, B extends number, AreNegative = [IsNeg
59
60
  ? SubtractPositives<A, B>
60
61
  : AreNegative extends [true, true]
61
62
  // When both numbers are negative we subtract the absolute values and then reverse the sign
62
- ? ReverseSign<SubtractPositives<NumberAbsolute<A>, NumberAbsolute<B>>>
63
+ ? ReverseSign<SubtractPositives<Absolute<A>, Absolute<B>>>
63
64
  // When the signs are different we can add the absolute values and then reverse the sign if A < B
64
- : [...TupleOf<NumberAbsolute<A>>, ...TupleOf<NumberAbsolute<B>>] extends infer R extends unknown[]
65
+ : [...TupleOf<Absolute<A>>, ...TupleOf<Absolute<B>>] extends infer R extends unknown[]
65
66
  ? LessThan<A, B> extends true ? ReverseSign<R['length']> : R['length']
66
67
  : never;
67
68
 
package/source/sum.d.ts CHANGED
@@ -1,7 +1,8 @@
1
1
  import type {TupleOf} from './tuple-of.d.ts';
2
- import type {NumberAbsolute, TupleMax, ReverseSign} from './internal/index.d.ts';
2
+ import type {TupleMax, ReverseSign} from './internal/index.d.ts';
3
3
  import type {PositiveInfinity, NegativeInfinity, IsNegative} from './numeric.d.ts';
4
4
  import type {Subtract} from './subtract.d.ts';
5
+ import type {Absolute} from './absolute.d.ts';
5
6
 
6
7
  /**
7
8
  Returns the sum of two numbers.
@@ -57,11 +58,11 @@ type SumPostChecks<A extends number, B extends number, AreNegative = [IsNegative
57
58
  ? SumPositives<A, B>
58
59
  : AreNegative extends [true, true]
59
60
  // When both numbers are negative we add the absolute values and then reverse the sign
60
- ? ReverseSign<SumPositives<NumberAbsolute<A>, NumberAbsolute<B>>>
61
+ ? ReverseSign<SumPositives<Absolute<A>, Absolute<B>>>
61
62
  // When the signs are different we can subtract the absolute values, remove the sign
62
63
  // and then reverse the sign if the larger absolute value is negative
63
- : NumberAbsolute<Subtract<NumberAbsolute<A>, NumberAbsolute<B>>> extends infer Result extends number
64
- ? TupleMax<[NumberAbsolute<A>, NumberAbsolute<B>]> extends infer Max_ extends number
64
+ : Absolute<Subtract<Absolute<A>, Absolute<B>>> extends infer Result extends number
65
+ ? TupleMax<[Absolute<A>, Absolute<B>]> extends infer Max_ extends number
65
66
  ? Max_ extends A | B
66
67
  // The larger absolute value is positive, so the result is positive
67
68
  ? Result
@@ -8,12 +8,10 @@ export type TagContainer<Token> = {
8
8
  type Tag<Token extends PropertyKey, TagMetadata> = TagContainer<{[K in Token]: TagMetadata}>;
9
9
 
10
10
  /**
11
- Attach a "tag" to an arbitrary type. This allows you to create distinct types, that aren't assignable to one another, for distinct concepts in your program that should not be interchangeable, even if their runtime values have the same type. (See examples.)
11
+ Create a [tagged type](https://medium.com/@KevinBGreene/surviving-the-typescript-ecosystem-branding-and-type-tagging-6cf6e516523d) that can support [multiple tags](https://github.com/sindresorhus/type-fest/issues/665) and [per-tag metadata](https://medium.com/@ethanresnick/advanced-typescript-tagged-types-improved-with-type-level-metadata-5072fc125fcf).
12
12
 
13
13
  A type returned by `Tagged` can be passed to `Tagged` again, to create a type with multiple tags.
14
14
 
15
- [Read more about tagged types.](https://medium.com/@KevinBGreene/surviving-the-typescript-ecosystem-branding-and-type-tagging-6cf6e516523d)
16
-
17
15
  A tag's name is usually a string (and must be a string, number, or symbol), but each application of a tag can also contain an arbitrary type as its "metadata". See {@link GetTagMetadata} for examples and explanation.
18
16
 
19
17
  A type `A` returned by `Tagged` is assignable to another type `B` returned by `Tagged` if and only if:
@@ -100,7 +98,7 @@ const parsed = parse(x); // The type of `parsed` is { hello: string }
100
98
  export type GetTagMetadata<Type extends Tag<TagName, unknown>, TagName extends PropertyKey> = Type[typeof tag][TagName];
101
99
 
102
100
  /**
103
- Revert a tagged type back to its original type by removing all tags.
101
+ Get the untagged portion of a tagged type created with `Tagged`.
104
102
 
105
103
  Why is this necessary?
106
104
 
@@ -129,7 +127,7 @@ type WontWork = UnwrapTagged<string>;
129
127
  @category Type
130
128
  */
131
129
  export type UnwrapTagged<TaggedType extends Tag<PropertyKey, any>> =
132
- RemoveAllTags<TaggedType>;
130
+ RemoveAllTags<TaggedType>;
133
131
 
134
132
  type RemoveAllTags<T> = T extends Tag<PropertyKey, any>
135
133
  ? {