@dereekb/util 13.16.0 → 13.18.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.
@@ -1,8 +1,8 @@
1
1
  {
2
2
  "name": "@dereekb/util/eslint",
3
- "version": "13.16.0",
3
+ "version": "13.18.0",
4
4
  "peerDependencies": {
5
- "@dereekb/util": "13.16.0",
5
+ "@dereekb/util": "13.18.0",
6
6
  "@typescript-eslint/utils": "8.59.3"
7
7
  },
8
8
  "devDependencies": {
@@ -1,8 +1,8 @@
1
1
  {
2
2
  "name": "@dereekb/util/fetch",
3
- "version": "13.16.0",
3
+ "version": "13.18.0",
4
4
  "peerDependencies": {
5
- "@dereekb/util": "13.16.0",
5
+ "@dereekb/util": "13.18.0",
6
6
  "make-error": "^1.3.6",
7
7
  "fast-content-type-parse": "^3.0.0"
8
8
  },
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@dereekb/util",
3
- "version": "13.16.0",
3
+ "version": "13.18.0",
4
4
  "sideEffects": false,
5
5
  "exports": {
6
6
  "./test": {
package/src/lib/type.d.ts CHANGED
@@ -4,6 +4,51 @@ import { type Maybe } from './value/maybe.type';
4
4
  * Boolean, string or number value.
5
5
  */
6
6
  export type PrimativeValue = boolean | string | number;
7
+ /**
8
+ * Phantom key used to nominally brand a primitive type.
9
+ *
10
+ * Declared (never defined) so it exists only in the type system and carries no
11
+ * runtime cost. Two `Brand<number, A>` / `Brand<number, B>` types are distinct
12
+ * whenever `A !== B`, which is what gives branded ids/keys their nominal identity
13
+ * despite sharing the same underlying primitive at runtime.
14
+ */
15
+ export declare const BRAND: unique symbol;
16
+ /**
17
+ * Nominally brands a primitive `TValue` with the compile-time-only tag `TBrand`.
18
+ *
19
+ * The brand is a zero-cost nominal type: the `[BRAND]` phantom key is erased at
20
+ * runtime, so a `Brand<number, 'UserId'>` is just a `number` once compiled, but
21
+ * the compiler refuses to mix it with a `Brand<number, 'PostId'>` or with a bare
22
+ * `number`. Use it to stop two structurally identical primitives (two id spaces,
23
+ * a raw count vs. a currency amount, ciphertext vs. plaintext, ...) from being
24
+ * accidentally interchanged.
25
+ *
26
+ * Branded values are minted at a trusted edge — a parser, a decoder, or an `as`
27
+ * assertion inside a constructor function — and then flow through the rest of the
28
+ * code as the branded type, so the "is this the right kind of value?" check is
29
+ * paid once rather than at every call site.
30
+ *
31
+ * @typeParam TValue - The underlying runtime representation (e.g. `number`, `string`).
32
+ * @typeParam TBrand - A unique string tag distinguishing this brand from others.
33
+ *
34
+ * @example
35
+ * ```ts
36
+ * type UserId = Brand<number, 'UserId'>;
37
+ * type PostId = Brand<number, 'PostId'>;
38
+ *
39
+ * function loadUser(id: UserId): User { ... }
40
+ *
41
+ * const userId = 10 as UserId;
42
+ * const postId = 10 as PostId;
43
+ *
44
+ * loadUser(userId); // ok
45
+ * loadUser(postId); // compile error: PostId is not assignable to UserId
46
+ * loadUser(10); // compile error: number is not assignable to UserId
47
+ * ```
48
+ */
49
+ export type Brand<TValue, TBrand extends string> = TValue & {
50
+ readonly [BRAND]: TBrand;
51
+ };
7
52
  /**
8
53
  * Open-ended union of known string literals `T` plus an arbitrary string fallback.
9
54
  *
package/test/package.json CHANGED
@@ -1,8 +1,8 @@
1
1
  {
2
2
  "name": "@dereekb/util/test",
3
- "version": "13.16.0",
3
+ "version": "13.18.0",
4
4
  "peerDependencies": {
5
- "@dereekb/util": "13.16.0",
5
+ "@dereekb/util": "13.18.0",
6
6
  "make-error": "^1.3.6"
7
7
  },
8
8
  "exports": {