@xsai/stream-object 0.2.0-beta.2 → 0.2.0-beta.3

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 (2) hide show
  1. package/dist/index.d.ts +149 -45
  2. package/package.json +2 -2
package/dist/index.d.ts CHANGED
@@ -22,6 +22,146 @@ declare global {
22
22
  }
23
23
  }
24
24
 
25
+ /**
26
+ Convert a union type to an intersection type using [distributive conditional types](https://www.typescriptlang.org/docs/handbook/release-notes/typescript-2-8.html#distributive-conditional-types).
27
+
28
+ Inspired by [this Stack Overflow answer](https://stackoverflow.com/a/50375286/2172153).
29
+
30
+ @example
31
+ ```
32
+ import type {UnionToIntersection} from 'type-fest';
33
+
34
+ type Union = {the(): void} | {great(arg: string): void} | {escape: boolean};
35
+
36
+ type Intersection = UnionToIntersection<Union>;
37
+ //=> {the(): void; great(arg: string): void; escape: boolean};
38
+ ```
39
+
40
+ A more applicable example which could make its way into your library code follows.
41
+
42
+ @example
43
+ ```
44
+ import type {UnionToIntersection} from 'type-fest';
45
+
46
+ class CommandOne {
47
+ commands: {
48
+ a1: () => undefined,
49
+ b1: () => undefined,
50
+ }
51
+ }
52
+
53
+ class CommandTwo {
54
+ commands: {
55
+ a2: (argA: string) => undefined,
56
+ b2: (argB: string) => undefined,
57
+ }
58
+ }
59
+
60
+ const union = [new CommandOne(), new CommandTwo()].map(instance => instance.commands);
61
+ type Union = typeof union;
62
+ //=> {a1(): void; b1(): void} | {a2(argA: string): void; b2(argB: string): void}
63
+
64
+ type Intersection = UnionToIntersection<Union>;
65
+ //=> {a1(): void; b1(): void; a2(argA: string): void; b2(argB: string): void}
66
+ ```
67
+
68
+ @category Type
69
+ */
70
+ type UnionToIntersection<Union> = (
71
+ // `extends unknown` is always going to be the case and is used to convert the
72
+ // `Union` into a [distributive conditional
73
+ // type](https://www.typescriptlang.org/docs/handbook/release-notes/typescript-2-8.html#distributive-conditional-types).
74
+ Union extends unknown
75
+ // The union type is used as the only argument to a function since the union
76
+ // of function arguments is an intersection.
77
+ ? (distributedUnion: Union) => void
78
+ // This won't happen.
79
+ : never
80
+ // Infer the `Intersection` type since TypeScript represents the positional
81
+ // arguments of unions of functions as an intersection of the union.
82
+ ) extends ((mergedIntersection: infer Intersection) => void)
83
+ // The `& Union` is to allow indexing by the resulting type
84
+ ? Intersection & Union
85
+ : never;
86
+
87
+ /**
88
+ Create a union of all keys from a given type, even those exclusive to specific union members.
89
+
90
+ Unlike the native `keyof` keyword, which returns keys present in **all** union members, this type returns keys from **any** member.
91
+
92
+ @link https://stackoverflow.com/a/49402091
93
+
94
+ @example
95
+ ```
96
+ import type {KeysOfUnion} from 'type-fest';
97
+
98
+ type A = {
99
+ common: string;
100
+ a: number;
101
+ };
102
+
103
+ type B = {
104
+ common: string;
105
+ b: string;
106
+ };
107
+
108
+ type C = {
109
+ common: string;
110
+ c: boolean;
111
+ };
112
+
113
+ type Union = A | B | C;
114
+
115
+ type CommonKeys = keyof Union;
116
+ //=> 'common'
117
+
118
+ type AllKeys = KeysOfUnion<Union>;
119
+ //=> 'common' | 'a' | 'b' | 'c'
120
+ ```
121
+
122
+ @category Object
123
+ */
124
+ type KeysOfUnion<ObjectType> =
125
+ // Hack to fix https://github.com/sindresorhus/type-fest/issues/1008
126
+ keyof UnionToIntersection<ObjectType extends unknown ? Record<keyof ObjectType, never> : never>;
127
+
128
+ /**
129
+ Extract all optional keys from the given type.
130
+
131
+ This is useful when you want to create a new type that contains different type values for the optional keys only.
132
+
133
+ @example
134
+ ```
135
+ import type {OptionalKeysOf, Except} from 'type-fest';
136
+
137
+ interface User {
138
+ name: string;
139
+ surname: string;
140
+
141
+ luckyNumber?: number;
142
+ }
143
+
144
+ const REMOVE_FIELD = Symbol('remove field symbol');
145
+ type UpdateOperation<Entity extends object> = Except<Partial<Entity>, OptionalKeysOf<Entity>> & {
146
+ [Key in OptionalKeysOf<Entity>]?: Entity[Key] | typeof REMOVE_FIELD;
147
+ };
148
+
149
+ const update1: UpdateOperation<User> = {
150
+ name: 'Alice'
151
+ };
152
+
153
+ const update2: UpdateOperation<User> = {
154
+ name: 'Bob',
155
+ luckyNumber: REMOVE_FIELD
156
+ };
157
+ ```
158
+
159
+ @category Utilities
160
+ */
161
+ type OptionalKeysOf<BaseType extends object> = KeysOfUnion<{
162
+ [Key in keyof BaseType as BaseType extends Record<Key, BaseType[Key]> ? never : Key]: never
163
+ }>;
164
+
25
165
  /**
26
166
  Extract all required keys from the given type.
27
167
 
@@ -46,11 +186,10 @@ const validator2 = createValidation<User>('surname', value => value.length < 25)
46
186
 
47
187
  @category Utilities
48
188
  */
49
- type RequiredKeysOf<BaseType extends object> = Exclude<{
50
- [Key in keyof BaseType]: BaseType extends Record<Key, BaseType[Key]>
51
- ? Key
52
- : never
53
- }[keyof BaseType], undefined>;
189
+ type RequiredKeysOf<BaseType extends object> =
190
+ BaseType extends unknown // For distributing `BaseType`
191
+ ? Exclude<keyof BaseType, OptionalKeysOf<BaseType>>
192
+ : never; // Should never happen
54
193
 
55
194
  /**
56
195
  Returns a boolean for whether the given type is `never`.
@@ -426,45 +565,6 @@ type IfAny<T, TypeIfAny = true, TypeIfNotAny = false> = (
426
565
  IsAny<T> extends true ? TypeIfAny : TypeIfNotAny
427
566
  );
428
567
 
429
- /**
430
- Extract all optional keys from the given type.
431
-
432
- This is useful when you want to create a new type that contains different type values for the optional keys only.
433
-
434
- @example
435
- ```
436
- import type {OptionalKeysOf, Except} from 'type-fest';
437
-
438
- interface User {
439
- name: string;
440
- surname: string;
441
-
442
- luckyNumber?: number;
443
- }
444
-
445
- const REMOVE_FIELD = Symbol('remove field symbol');
446
- type UpdateOperation<Entity extends object> = Except<Partial<Entity>, OptionalKeysOf<Entity>> & {
447
- [Key in OptionalKeysOf<Entity>]?: Entity[Key] | typeof REMOVE_FIELD;
448
- };
449
-
450
- const update1: UpdateOperation<User> = {
451
- name: 'Alice'
452
- };
453
-
454
- const update2: UpdateOperation<User> = {
455
- name: 'Bob',
456
- luckyNumber: REMOVE_FIELD
457
- };
458
- ```
459
-
460
- @category Utilities
461
- */
462
- type OptionalKeysOf<BaseType extends object> = Exclude<{
463
- [Key in keyof BaseType]: BaseType extends Record<Key, BaseType[Key]>
464
- ? never
465
- : Key
466
- }[keyof BaseType], undefined>;
467
-
468
568
  /**
469
569
  Matches any primitive, `void`, `Date`, or `RegExp` value.
470
570
  */
@@ -531,7 +631,11 @@ type ApplyDefaultOptions<
531
631
  IfNever<SpecifiedOptions, Defaults,
532
632
  Simplify<Merge<Defaults, {
533
633
  [Key in keyof SpecifiedOptions
534
- as Key extends OptionalKeysOf<Options> ? undefined extends SpecifiedOptions[Key] ? never : Key : Key
634
+ as Key extends OptionalKeysOf<Options>
635
+ ? Extract<SpecifiedOptions[Key], undefined> extends never
636
+ ? Key
637
+ : never
638
+ : Key
535
639
  ]: SpecifiedOptions[Key]
536
640
  }> & Required<Options>> // `& Required<Options>` ensures that `ApplyDefaultOptions<SomeOption, ...>` is always assignable to `Required<SomeOption>`
537
641
  >>;
package/package.json CHANGED
@@ -1,7 +1,7 @@
1
1
  {
2
2
  "name": "@xsai/stream-object",
3
3
  "type": "module",
4
- "version": "0.2.0-beta.2",
4
+ "version": "0.2.0-beta.3",
5
5
  "description": "extra-small AI SDK for Browser, Node.js, Deno, Bun or Edge Runtime.",
6
6
  "author": "Moeru AI",
7
7
  "license": "MIT",
@@ -35,7 +35,7 @@
35
35
  "devDependencies": {
36
36
  "@valibot/to-json-schema": "^1.0.0",
37
37
  "best-effort-json-parser": "^1.1.3",
38
- "type-fest": "^4.38.0",
38
+ "type-fest": "^4.39.0",
39
39
  "valibot": "^1.0.0"
40
40
  },
41
41
  "scripts": {