complete-common 2.28.0 → 2.30.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 (52) hide show
  1. package/dist/functions/array.d.ts.map +1 -1
  2. package/dist/functions/assert.d.cts +4 -2
  3. package/dist/functions/assert.d.mts +4 -2
  4. package/dist/functions/assert.d.ts +4 -2
  5. package/dist/functions/assert.d.ts.map +1 -1
  6. package/dist/functions/enums.d.cts +2 -2
  7. package/dist/functions/enums.d.mts +2 -2
  8. package/dist/functions/enums.d.ts +2 -2
  9. package/dist/functions/set.d.cts +1 -1
  10. package/dist/functions/set.d.mts +1 -1
  11. package/dist/functions/set.d.ts +1 -1
  12. package/dist/functions/set.d.ts.map +1 -1
  13. package/dist/functions/sort.d.ts.map +1 -1
  14. package/dist/functions/string.d.ts.map +1 -1
  15. package/dist/functions/tuple.d.cts +2 -2
  16. package/dist/functions/tuple.d.mts +2 -2
  17. package/dist/functions/tuple.d.ts +2 -2
  18. package/dist/functions/types.d.cts +1 -1
  19. package/dist/functions/types.d.mts +1 -1
  20. package/dist/functions/types.d.ts +1 -1
  21. package/dist/functions/utils.d.cts +2 -4
  22. package/dist/functions/utils.d.mts +2 -4
  23. package/dist/functions/utils.d.ts +2 -4
  24. package/dist/functions/utils.d.ts.map +1 -1
  25. package/dist/index.cjs +42 -42
  26. package/dist/index.d.cts +2 -0
  27. package/dist/index.d.mts +2 -0
  28. package/dist/index.d.ts +2 -0
  29. package/dist/index.d.ts.map +1 -1
  30. package/dist/index.mjs +42 -43
  31. package/dist/types/Expect.d.cts +6 -0
  32. package/dist/types/Expect.d.mts +6 -0
  33. package/dist/types/Expect.d.ts +6 -0
  34. package/dist/types/Expect.d.ts.map +1 -0
  35. package/dist/types/KeysMatch.d.cts +25 -0
  36. package/dist/types/KeysMatch.d.mts +25 -0
  37. package/dist/types/KeysMatch.d.ts +25 -0
  38. package/dist/types/KeysMatch.d.ts.map +1 -0
  39. package/package.json +4 -4
  40. package/src/functions/array.ts +2 -8
  41. package/src/functions/assert.ts +16 -4
  42. package/src/functions/enums.ts +2 -2
  43. package/src/functions/object.ts +1 -1
  44. package/src/functions/set.ts +2 -7
  45. package/src/functions/sort.ts +1 -3
  46. package/src/functions/string.ts +28 -23
  47. package/src/functions/tuple.ts +2 -2
  48. package/src/functions/types.ts +1 -1
  49. package/src/functions/utils.ts +13 -11
  50. package/src/index.ts +2 -0
  51. package/src/types/Expect.ts +5 -0
  52. package/src/types/KeysMatch.ts +28 -0
@@ -7,8 +7,8 @@
7
7
  // When regexes are located at the root instead of inside the function, the functions are tested to
8
8
  // perform 11% faster.
9
9
 
10
- const FLOAT_REGEX = /^-?\d*\.?\d+$/;
11
- const INTEGER_REGEX = /^-?\d+$/;
10
+ const FLOAT_REGEX = /^-?(?:\d+(?:\.\d+)?|\.\d+)$/v;
11
+ const INTEGER_REGEX = /^-?\d+$/v;
12
12
 
13
13
  /**
14
14
  * Helper function to get an iterator of integers with the specified range, inclusive on the lower
@@ -99,7 +99,7 @@ export function isKeyOf<T extends object>(
99
99
  key: PropertyKey,
100
100
  target: T,
101
101
  ): key is keyof T {
102
- return key in target;
102
+ return Object.hasOwn(target, key);
103
103
  }
104
104
 
105
105
  /**
@@ -115,10 +115,8 @@ export function noop(): void {}
115
115
  * - `undefined` is returned instead of `Number.NaN`, which is helpful in conjunction with
116
116
  * TypeScript type narrowing patterns.
117
117
  * - Strings that are a mixture of numbers and letters will result in undefined instead of the part
118
- * of the string that is the number. (e.g. "1a" --> undefined instead of "1a" --> 1)
118
+ * of the string that is the number. (e.g., "1a" --> undefined instead of "1a" --> 1)
119
119
  * - Non-strings will result in undefined instead of being coerced to a number.
120
- *
121
- * @param string A string to convert to an integer.
122
120
  */
123
121
  export function parseFloatSafe(string: string): number | undefined {
124
122
  if (typeof string !== "string") {
@@ -128,11 +126,13 @@ export function parseFloatSafe(string: string): number | undefined {
128
126
  const trimmedString = string.trim();
129
127
 
130
128
  // If the string does not entirely consist of numbers, return undefined.
131
- if (FLOAT_REGEX.exec(trimmedString) === null) {
129
+ if (!FLOAT_REGEX.test(trimmedString)) {
132
130
  return undefined;
133
131
  }
134
132
 
135
- const number = Number.parseFloat(trimmedString);
133
+ // The "Number" constructor is used instead of "Number.parseFloat":
134
+ // https://github.com/sindresorhus/eslint-plugin-unicorn/blob/main/docs/rules/prefer-number-coercion.md
135
+ const number = Number(trimmedString);
136
136
  return Number.isNaN(number) ? undefined : number;
137
137
  }
138
138
 
@@ -142,7 +142,7 @@ export function parseFloatSafe(string: string): number | undefined {
142
142
  * - `undefined` is returned instead of `Number.NaN`, which is helpful in conjunction with
143
143
  * TypeScript type narrowing patterns.
144
144
  * - Strings that are a mixture of numbers and letters will result in undefined instead of the part
145
- * of the string that is the number. (e.g. "1a" --> undefined instead of "1a" --> 1)
145
+ * of the string that is the number. (e.g., "1a" --> undefined instead of "1a" --> 1)
146
146
  * - Non-strings will result in undefined instead of being coerced to a number.
147
147
  *
148
148
  * If you have to use a radix other than 10, use the vanilla `Number.parseInt` function instead,
@@ -156,11 +156,13 @@ export function parseIntSafe(string: string): number | undefined {
156
156
  const trimmedString = string.trim();
157
157
 
158
158
  // If the string does not entirely consist of numbers, return undefined.
159
- if (INTEGER_REGEX.exec(trimmedString) === null) {
159
+ if (!INTEGER_REGEX.test(trimmedString)) {
160
160
  return undefined;
161
161
  }
162
162
 
163
- const number = Number.parseInt(trimmedString, 10);
163
+ // The "Number" constructor is used instead of "Number.parseInt":
164
+ // https://github.com/sindresorhus/eslint-plugin-unicorn/blob/main/docs/rules/prefer-number-coercion.md
165
+ const number = Math.trunc(Number(trimmedString));
164
166
  return Number.isNaN(number) ? undefined : number;
165
167
  }
166
168
 
package/src/index.ts CHANGED
@@ -17,8 +17,10 @@ export type * from "./interfaces/SemanticVersion.js";
17
17
  export type * from "./types/AddSubtract.js";
18
18
  export type * from "./types/CompositionTypeSatisfiesEnum.js";
19
19
  export type * from "./types/ERange.js";
20
+ export type * from "./types/Expect.js";
20
21
  export type * from "./types/Immutable.js";
21
22
  export type * from "./types/IRange.js";
23
+ export type * from "./types/KeysMatch.js";
22
24
  export type * from "./types/NaturalNumbersLessThan.js";
23
25
  export type * from "./types/NaturalNumbersLessThanOrEqualTo.js";
24
26
  export type * from "./types/ObjectValues.js";
@@ -0,0 +1,5 @@
1
+ /**
2
+ * Helper type used for testing other interfaces/types. Only `true` is assignable, anything else
3
+ * errors.
4
+ */
5
+ export type Expect<T extends true> = T;
@@ -0,0 +1,28 @@
1
+ /**
2
+ * Helper type to ensure that an array of keys matches an interface.
3
+ *
4
+ * For example:
5
+ *
6
+ * ```ts
7
+ * interface Foo {
8
+ * arg1: string;
9
+ * arg2: string;
10
+ * }
11
+ *
12
+ * const FOO_KEYS = ["arg1", "arg2"] as const;
13
+ * type _ = Expect<KeysMatch<Foo, typeof FOO_KEYS>>;
14
+ * ```
15
+ */
16
+ export type KeysMatch<T, Keys extends readonly PropertyKey[]> = [
17
+ keyof T,
18
+ ] extends [Keys[number]]
19
+ ? [Keys[number]] extends [keyof T]
20
+ ? true
21
+ : {
22
+ error: "Extra keys not in interface";
23
+ extra: Exclude<Keys[number], keyof T>;
24
+ }
25
+ : {
26
+ error: "Missing keys from interface";
27
+ missing: Exclude<keyof T, Keys[number]>;
28
+ };