@alessiofrittoli/type-utils 2.0.0 → 2.1.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,4 +1,3 @@
1
- //#region src/globals/extenders/json.d.ts
2
1
  declare class Stringified<T> extends String {
3
2
  private ___stringified;
4
3
  }
@@ -15,5 +14,4 @@ declare global {
15
14
  json<T = any>(): Promise<T>;
16
15
  }
17
16
  }
18
- //#endregion
19
17
  export {};
@@ -1,4 +1,3 @@
1
- //#region src/globals/extenders/json.d.ts
2
1
  declare class Stringified<T> extends String {
3
2
  private ___stringified;
4
3
  }
@@ -15,5 +14,4 @@ declare global {
15
14
  json<T = any>(): Promise<T>;
16
15
  }
17
16
  }
18
- //#endregion
19
17
  export {};
package/dist/index.d.cts CHANGED
@@ -1,4 +1,3 @@
1
- //#region src/unflat-dot-keys.d.ts
2
1
  type RequiredKey<T> = { [K in keyof T]-?: object extends Pick<T, K> ? never : K; }[keyof T];
3
2
  type Head<K> = K extends `${infer H}.${string}` ? H : never;
4
3
  /**
@@ -33,8 +32,6 @@ type UnflatDotKeys<T, K extends string = never> = Unflat<PickDotKeys<T, K>, fals
33
32
  * @template K The object interface specific key to work with (`${K}.*`).
34
33
  */
35
34
  type RecursivelyUnflatDotKeys<T, K extends string = never> = Unflat<PickDotKeys<T, K>, true>;
36
- //#endregion
37
- //#region src/index.d.ts
38
35
  /**
39
36
  * Get the Type of the Value of a object/array property.
40
37
  *
@@ -146,5 +143,62 @@ export type NonNullableFields<T> = { [P in keyof T]: NonNullable<T[P]>; };
146
143
  * ```
147
144
  */
148
145
  export type MergedEnumValue<T> = { [K in keyof T]: { [K2 in keyof T[K]]: T[K][K2]; }[keyof T[K]]; }[keyof T];
149
- //#endregion
146
+ /**
147
+ * Builds a discriminated union of `[event, args]` tuples from an event map.
148
+ *
149
+ * Each key of the given map becomes a tuple whose first element is the event name
150
+ * and whose second element is its payload type. Since the tuples are discriminated
151
+ * by the event name, checking `event` narrows `args` to the matching payload.
152
+ *
153
+ * @template M The event map, where each key is an event name and each value is its payload type.
154
+ *
155
+ * @example
156
+ * ```ts
157
+ * interface Events {
158
+ * play: { position: number }
159
+ * error: Error
160
+ * }
161
+ *
162
+ * type OnEventHandler = (...args: MappedArgs<Events>) => void
163
+ *
164
+ * const onEvent: OnEventHandler = (event, args): void => {
165
+ * if (event === 'play') {
166
+ * console.log(args.position) // `args` is narrowed to `{ position: number }`
167
+ * }
168
+ * if (event === 'error') {
169
+ * console.log(args) // `args` is narrowed to `Error`
170
+ * }
171
+ * }
172
+ *
173
+ * onEvent('play', { position: 0 })
174
+ * onEvent('error', new Error())
175
+ * ```
176
+ *
177
+ * ---
178
+ *
179
+ * @example
180
+ * ```ts
181
+ * interface Events {
182
+ * play: [data: { position: number }]
183
+ * error: [error: Error]
184
+ * }
185
+ *
186
+ * type OnEventHandler = (...args: MappedArgs<Events>) => void
187
+ *
188
+ * const onEvent: OnEventHandler = (event, args): void => {
189
+ * if (event === 'play') {
190
+ * const [payload] = args
191
+ * console.log(payload.position) // `args` is narrowed to [`{ position: number }`]
192
+ * }
193
+ * if (event === 'error') {
194
+ * const [error] = args // `args` is narrowed to [`Error`]
195
+ * console.log(error)
196
+ * }
197
+ * }
198
+ *
199
+ * onEvent('play', [{ position: 0 }])
200
+ * onEvent('error', [new Error()])
201
+ * ```
202
+ */
203
+ export type MappedArgs<M> = { [K in keyof M]: [event: K, args: M[K]]; }[keyof M];
150
204
  export type { RecursivelyUnflatDotKeys, UnflatDotKeys };
package/dist/index.d.mts CHANGED
@@ -1,4 +1,3 @@
1
- //#region src/unflat-dot-keys.d.ts
2
1
  type RequiredKey<T> = { [K in keyof T]-?: object extends Pick<T, K> ? never : K; }[keyof T];
3
2
  type Head<K> = K extends `${infer H}.${string}` ? H : never;
4
3
  /**
@@ -33,8 +32,6 @@ type UnflatDotKeys<T, K extends string = never> = Unflat<PickDotKeys<T, K>, fals
33
32
  * @template K The object interface specific key to work with (`${K}.*`).
34
33
  */
35
34
  type RecursivelyUnflatDotKeys<T, K extends string = never> = Unflat<PickDotKeys<T, K>, true>;
36
- //#endregion
37
- //#region src/index.d.ts
38
35
  /**
39
36
  * Get the Type of the Value of a object/array property.
40
37
  *
@@ -146,5 +143,62 @@ export type NonNullableFields<T> = { [P in keyof T]: NonNullable<T[P]>; };
146
143
  * ```
147
144
  */
148
145
  export type MergedEnumValue<T> = { [K in keyof T]: { [K2 in keyof T[K]]: T[K][K2]; }[keyof T[K]]; }[keyof T];
149
- //#endregion
146
+ /**
147
+ * Builds a discriminated union of `[event, args]` tuples from an event map.
148
+ *
149
+ * Each key of the given map becomes a tuple whose first element is the event name
150
+ * and whose second element is its payload type. Since the tuples are discriminated
151
+ * by the event name, checking `event` narrows `args` to the matching payload.
152
+ *
153
+ * @template M The event map, where each key is an event name and each value is its payload type.
154
+ *
155
+ * @example
156
+ * ```ts
157
+ * interface Events {
158
+ * play: { position: number }
159
+ * error: Error
160
+ * }
161
+ *
162
+ * type OnEventHandler = (...args: MappedArgs<Events>) => void
163
+ *
164
+ * const onEvent: OnEventHandler = (event, args): void => {
165
+ * if (event === 'play') {
166
+ * console.log(args.position) // `args` is narrowed to `{ position: number }`
167
+ * }
168
+ * if (event === 'error') {
169
+ * console.log(args) // `args` is narrowed to `Error`
170
+ * }
171
+ * }
172
+ *
173
+ * onEvent('play', { position: 0 })
174
+ * onEvent('error', new Error())
175
+ * ```
176
+ *
177
+ * ---
178
+ *
179
+ * @example
180
+ * ```ts
181
+ * interface Events {
182
+ * play: [data: { position: number }]
183
+ * error: [error: Error]
184
+ * }
185
+ *
186
+ * type OnEventHandler = (...args: MappedArgs<Events>) => void
187
+ *
188
+ * const onEvent: OnEventHandler = (event, args): void => {
189
+ * if (event === 'play') {
190
+ * const [payload] = args
191
+ * console.log(payload.position) // `args` is narrowed to [`{ position: number }`]
192
+ * }
193
+ * if (event === 'error') {
194
+ * const [error] = args // `args` is narrowed to [`Error`]
195
+ * console.log(error)
196
+ * }
197
+ * }
198
+ *
199
+ * onEvent('play', [{ position: 0 }])
200
+ * onEvent('error', [new Error()])
201
+ * ```
202
+ */
203
+ export type MappedArgs<M> = { [K in keyof M]: [event: K, args: M[K]]; }[keyof M];
150
204
  export type { RecursivelyUnflatDotKeys, UnflatDotKeys };
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@alessiofrittoli/type-utils",
3
- "version": "2.0.0",
3
+ "version": "2.1.0",
4
4
  "description": "Lightweight TypeScript types utilities",
5
5
  "type": "module",
6
6
  "author": {
@@ -63,30 +63,30 @@
63
63
  },
64
64
  "sideEffects": false,
65
65
  "peerDependencies": {
66
- "@alessiofrittoli/chain-functions": "^2.7.0",
67
- "@alessiofrittoli/node-scripts": "^4.1.0"
66
+ "@alessiofrittoli/chain-functions": "^2.8.0",
67
+ "@alessiofrittoli/node-scripts": "^4.2.0"
68
68
  },
69
69
  "devDependencies": {
70
- "@alessiofrittoli/chain-functions": "^2.7.0",
71
- "@alessiofrittoli/node-scripts": "^4.1.0",
72
- "@alessiofrittoli/package-configs": "^1.6.0",
70
+ "@alessiofrittoli/chain-functions": "^2.8.0",
71
+ "@alessiofrittoli/node-scripts": "^4.2.0",
72
+ "@alessiofrittoli/package-configs": "^1.9.0",
73
73
  "@types/node": "^24.19.1",
74
- "@vitest/coverage-v8": "^5.0.4",
74
+ "@vitest/coverage-v8": "^5.0.5",
75
75
  "concurrently": "^10.0.6",
76
76
  "http-server": "^14.1.1",
77
- "oxlint": "^1.88.0",
77
+ "oxlint": "^1.89.0",
78
+ "oxlint-tsgolint": "^7.0.2005",
78
79
  "prettier": "^3.9.10",
79
80
  "prettier-plugin-sort-imports": "^1.8.11",
80
- "tsdown": "^0.23.1",
81
- "typescript": "^6.0.3",
82
- "vite": "^8.3.4"
81
+ "tsdown": "^0.23.2",
82
+ "typescript": "^6.0.3"
83
83
  },
84
84
  "scripts": {
85
85
  "//1a": "*********************************************************************",
86
86
  "//1b": "******************** DEV - BUILD - LINT - RELEASE *******************",
87
87
  "//1c": "*********************************************************************",
88
88
  "dev": "tsdown --watch",
89
- "build": "pnpm lint && pnpm tsc && pnpm tsdown",
89
+ "build": "pnpm lint && pnpm tsdown",
90
90
  "lint": "oxlint --report-unused-disable-directives --max-warnings 0",
91
91
  "release": "node scripts/release.ts --verbose --npm",
92
92
  "//2a": "*********************************************************************",
@@ -13,4 +13,5 @@ const lastChainLink = () => () => {
13
13
  /** @type {import( '@alessiofrittoli/chain-functions/types' ).ChainFactory<() => void | Promise<void>>} */
14
14
  const chain = [tsSetup, lastChainLink]
15
15
 
16
+ // oxlint-disable-next-line typescript/no-floating-promises
16
17
  Chain.functions(chain)()