@xsai/stream-object 0.4.0-beta.9 → 0.4.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.
package/dist/index.d.ts CHANGED
@@ -1,5 +1,175 @@
1
1
  import { StreamTextOptions, StreamTextResult } from '@xsai/stream-text';
2
- import { Schema, Infer } from 'xsschema';
2
+ import { Schema } from 'xsschema';
3
+
4
+ /**
5
+ Matches any [primitive value](https://developer.mozilla.org/en-US/docs/Glossary/Primitive).
6
+
7
+ @category Type
8
+ */
9
+ type Primitive =
10
+ | null
11
+ | undefined
12
+ | string
13
+ | number
14
+ | boolean
15
+ | symbol
16
+ | bigint;
17
+
18
+ /**
19
+ Returns a boolean for whether the given type is `any`.
20
+
21
+ @link https://stackoverflow.com/a/49928360/1490091
22
+
23
+ Useful in type utilities, such as disallowing `any`s to be passed to a function.
24
+
25
+ @example
26
+ ```
27
+ import type {IsAny} from 'type-fest';
28
+
29
+ const typedObject = {a: 1, b: 2} as const;
30
+ const anyObject: any = {a: 1, b: 2};
31
+
32
+ function get<O extends (IsAny<O> extends true ? {} : Record<string, number>), K extends keyof O = keyof O>(object: O, key: K) {
33
+ return object[key];
34
+ }
35
+
36
+ const typedA = get(typedObject, 'a');
37
+ //=> 1
38
+
39
+ const anyA = get(anyObject, 'a');
40
+ //=> any
41
+ ```
42
+
43
+ @category Type Guard
44
+ @category Utilities
45
+ */
46
+ type IsAny<T> = 0 extends 1 & NoInfer<T> ? true : false;
47
+
48
+ /**
49
+ Returns a boolean for whether the given key is an optional key of type.
50
+
51
+ This is useful when writing utility types or schema validators that need to differentiate `optional` keys.
52
+
53
+ @example
54
+ ```
55
+ import type {IsOptionalKeyOf} from 'type-fest';
56
+
57
+ type User = {
58
+ name: string;
59
+ surname: string;
60
+
61
+ luckyNumber?: number;
62
+ };
63
+
64
+ type Admin = {
65
+ name: string;
66
+ surname?: string;
67
+ };
68
+
69
+ type T1 = IsOptionalKeyOf<User, 'luckyNumber'>;
70
+ //=> true
71
+
72
+ type T2 = IsOptionalKeyOf<User, 'name'>;
73
+ //=> false
74
+
75
+ type T3 = IsOptionalKeyOf<User, 'name' | 'luckyNumber'>;
76
+ //=> boolean
77
+
78
+ type T4 = IsOptionalKeyOf<User | Admin, 'name'>;
79
+ //=> false
80
+
81
+ type T5 = IsOptionalKeyOf<User | Admin, 'surname'>;
82
+ //=> boolean
83
+ ```
84
+
85
+ @category Type Guard
86
+ @category Utilities
87
+ */
88
+ type IsOptionalKeyOf<Type extends object, Key extends keyof Type> =
89
+ IsAny<Type | Key> extends true ? never
90
+ : Key extends keyof Type
91
+ ? Type extends Record<Key, Type[Key]>
92
+ ? false
93
+ : true
94
+ : false;
95
+
96
+ /**
97
+ Extract all optional keys from the given type.
98
+
99
+ This is useful when you want to create a new type that contains different type values for the optional keys only.
100
+
101
+ @example
102
+ ```
103
+ import type {OptionalKeysOf, Except} from 'type-fest';
104
+
105
+ type User = {
106
+ name: string;
107
+ surname: string;
108
+
109
+ luckyNumber?: number;
110
+ };
111
+
112
+ const REMOVE_FIELD = Symbol('remove field symbol');
113
+ type UpdateOperation<Entity extends object> = Except<Partial<Entity>, OptionalKeysOf<Entity>> & {
114
+ [Key in OptionalKeysOf<Entity>]?: Entity[Key] | typeof REMOVE_FIELD;
115
+ };
116
+
117
+ const update1: UpdateOperation<User> = {
118
+ name: 'Alice',
119
+ };
120
+
121
+ const update2: UpdateOperation<User> = {
122
+ name: 'Bob',
123
+ luckyNumber: REMOVE_FIELD,
124
+ };
125
+ ```
126
+
127
+ @category Utilities
128
+ */
129
+ type OptionalKeysOf<Type extends object> =
130
+ Type extends unknown // For distributing `Type`
131
+ ? (keyof {[Key in keyof Type as
132
+ IsOptionalKeyOf<Type, Key> extends false
133
+ ? never
134
+ : Key
135
+ ]: never
136
+ }) & keyof Type // Intersect with `keyof Type` to ensure result of `OptionalKeysOf<Type>` is always assignable to `keyof Type`
137
+ : never; // Should never happen
138
+
139
+ /**
140
+ Extract all required keys from the given type.
141
+
142
+ This is useful when you want to create a new type that contains different type values for the required keys only or use the list of keys for validation purposes, etc...
143
+
144
+ @example
145
+ ```
146
+ import type {RequiredKeysOf} from 'type-fest';
147
+
148
+ declare function createValidation<
149
+ Entity extends object,
150
+ Key extends RequiredKeysOf<Entity> = RequiredKeysOf<Entity>,
151
+ >(field: Key, validator: (value: Entity[Key]) => boolean): (entity: Entity) => boolean;
152
+
153
+ type User = {
154
+ name: string;
155
+ surname: string;
156
+ luckyNumber?: number;
157
+ };
158
+
159
+ const validator1 = createValidation<User>('name', value => value.length < 25);
160
+ const validator2 = createValidation<User>('surname', value => value.length < 25);
161
+
162
+ // @ts-expect-error
163
+ const validator3 = createValidation<User>('luckyNumber', value => value > 0);
164
+ // Error: Argument of type '"luckyNumber"' is not assignable to parameter of type '"name" | "surname"'.
165
+ ```
166
+
167
+ @category Utilities
168
+ */
169
+ type RequiredKeysOf<Type extends object> =
170
+ Type extends unknown // For distributing `Type`
171
+ ? Exclude<keyof Type, OptionalKeysOf<Type>>
172
+ : never; // Should never happen
3
173
 
4
174
  /**
5
175
  Returns a boolean for whether the given type is `never`.
@@ -14,29 +184,41 @@ Useful in type utilities, such as checking if something does not occur.
14
184
  ```
15
185
  import type {IsNever, And} from 'type-fest';
16
186
 
17
- // https://github.com/andnp/SimplyTyped/blob/master/src/types/strings.ts
18
- type AreStringsEqual<A extends string, B extends string> =
19
- And<
20
- IsNever<Exclude<A, B>> extends true ? true : false,
21
- IsNever<Exclude<B, A>> extends true ? true : false
22
- >;
187
+ type A = IsNever<never>;
188
+ //=> true
23
189
 
24
- type EndIfEqual<I extends string, O extends string> =
25
- AreStringsEqual<I, O> extends true
26
- ? never
27
- : void;
190
+ type B = IsNever<any>;
191
+ //=> false
28
192
 
29
- function endIfEqual<I extends string, O extends string>(input: I, output: O): EndIfEqual<I, O> {
30
- if (input === output) {
31
- process.exit(0);
32
- }
33
- }
193
+ type C = IsNever<unknown>;
194
+ //=> false
34
195
 
35
- endIfEqual('abc', 'abc');
36
- //=> never
196
+ type D = IsNever<never[]>;
197
+ //=> false
37
198
 
38
- endIfEqual('abc', '123');
39
- //=> void
199
+ type E = IsNever<object>;
200
+ //=> false
201
+
202
+ type F = IsNever<string>;
203
+ //=> false
204
+ ```
205
+
206
+ @example
207
+ ```
208
+ import type {IsNever} from 'type-fest';
209
+
210
+ type IsTrue<T> = T extends true ? true : false;
211
+
212
+ // When a distributive conditional is instantiated with `never`, the entire conditional results in `never`.
213
+ type A = IsTrue<never>;
214
+ // ^? type A = never
215
+
216
+ // If you don't want that behaviour, you can explicitly add an `IsNever` check before the distributive conditional.
217
+ type IsTrueFixed<T> =
218
+ IsNever<T> extends true ? false : T extends true ? true : false;
219
+
220
+ type B = IsTrueFixed<never>;
221
+ // ^? type B = false
40
222
  ```
41
223
 
42
224
  @category Type Guard
@@ -45,75 +227,125 @@ endIfEqual('abc', '123');
45
227
  type IsNever<T> = [T] extends [never] ? true : false;
46
228
 
47
229
  /**
48
- An if-else-like type that resolves depending on whether the given type is `never`.
230
+ An if-else-like type that resolves depending on whether the given `boolean` type is `true` or `false`.
231
+
232
+ Use-cases:
233
+ - You can use this in combination with `Is*` types to create an if-else-like experience. For example, `If<IsAny<any>, 'is any', 'not any'>`.
49
234
 
50
- @see {@link IsNever}
235
+ Note:
236
+ - Returns a union of if branch and else branch if the given type is `boolean` or `any`. For example, `If<boolean, 'Y', 'N'>` will return `'Y' | 'N'`.
237
+ - Returns the else branch if the given type is `never`. For example, `If<never, 'Y', 'N'>` will return `'N'`.
51
238
 
52
239
  @example
53
240
  ```
54
- import type {IfNever} from 'type-fest';
241
+ import type {If} from 'type-fest';
55
242
 
56
- type ShouldBeTrue = IfNever<never>;
57
- //=> true
243
+ type A = If<true, 'yes', 'no'>;
244
+ //=> 'yes'
245
+
246
+ type B = If<false, 'yes', 'no'>;
247
+ //=> 'no'
248
+
249
+ type C = If<boolean, 'yes', 'no'>;
250
+ //=> 'yes' | 'no'
58
251
 
59
- type ShouldBeBar = IfNever<'not never', 'foo', 'bar'>;
60
- //=> 'bar'
252
+ type D = If<any, 'yes', 'no'>;
253
+ //=> 'yes' | 'no'
254
+
255
+ type E = If<never, 'yes', 'no'>;
256
+ //=> 'no'
61
257
  ```
62
258
 
63
- @category Type Guard
64
- @category Utilities
65
- */
66
- type IfNever<T, TypeIfNever = true, TypeIfNotNever = false> = (
67
- IsNever<T> extends true ? TypeIfNever : TypeIfNotNever
68
- );
259
+ @example
260
+ ```
261
+ import type {If, IsAny, IsNever} from 'type-fest';
69
262
 
70
- // Can eventually be replaced with the built-in once this library supports
71
- // TS5.4+ only. Tracked in https://github.com/sindresorhus/type-fest/issues/848
72
- type NoInfer<T> = T extends infer U ? U : never;
263
+ type A = If<IsAny<unknown>, 'is any', 'not any'>;
264
+ //=> 'not any'
73
265
 
74
- /**
75
- Returns a boolean for whether the given type is `any`.
266
+ type B = If<IsNever<never>, 'is never', 'not never'>;
267
+ //=> 'is never'
268
+ ```
76
269
 
77
- @link https://stackoverflow.com/a/49928360/1490091
270
+ @example
271
+ ```
272
+ import type {If, IsEqual} from 'type-fest';
78
273
 
79
- Useful in type utilities, such as disallowing `any`s to be passed to a function.
274
+ type IfEqual<T, U, IfBranch, ElseBranch> = If<IsEqual<T, U>, IfBranch, ElseBranch>;
275
+
276
+ type A = IfEqual<string, string, 'equal', 'not equal'>;
277
+ //=> 'equal'
278
+
279
+ type B = IfEqual<string, number, 'equal', 'not equal'>;
280
+ //=> 'not equal'
281
+ ```
282
+
283
+ Note: Sometimes using the `If` type can make an implementation non–tail-recursive, which can impact performance. In such cases, it’s better to use a conditional directly. Refer to the following example:
80
284
 
81
285
  @example
82
286
  ```
83
- import type {IsAny} from 'type-fest';
287
+ import type {If, IsEqual, StringRepeat} from 'type-fest';
84
288
 
85
- const typedObject = {a: 1, b: 2} as const;
86
- const anyObject: any = {a: 1, b: 2};
289
+ type HundredZeroes = StringRepeat<'0', 100>;
87
290
 
88
- function get<O extends (IsAny<O> extends true ? {} : Record<string, number>), K extends keyof O = keyof O>(obj: O, key: K) {
89
- return obj[key];
90
- }
291
+ // The following implementation is not tail recursive
292
+ type Includes<S extends string, Char extends string> =
293
+ S extends `${infer First}${infer Rest}`
294
+ ? If<IsEqual<First, Char>,
295
+ 'found',
296
+ Includes<Rest, Char>>
297
+ : 'not found';
91
298
 
92
- const typedA = get(typedObject, 'a');
93
- //=> 1
299
+ // Hence, instantiations with long strings will fail
300
+ // @ts-expect-error
301
+ type Fails = Includes<HundredZeroes, '1'>;
302
+ // ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
303
+ // Error: Type instantiation is excessively deep and possibly infinite.
94
304
 
95
- const anyA = get(anyObject, 'a');
96
- //=> any
305
+ // However, if we use a simple conditional instead of `If`, the implementation becomes tail-recursive
306
+ type IncludesWithoutIf<S extends string, Char extends string> =
307
+ S extends `${infer First}${infer Rest}`
308
+ ? IsEqual<First, Char> extends true
309
+ ? 'found'
310
+ : IncludesWithoutIf<Rest, Char>
311
+ : 'not found';
312
+
313
+ // Now, instantiations with long strings will work
314
+ type Works = IncludesWithoutIf<HundredZeroes, '1'>;
315
+ //=> 'not found'
97
316
  ```
98
317
 
99
318
  @category Type Guard
100
319
  @category Utilities
101
320
  */
102
- type IsAny<T> = 0 extends 1 & NoInfer<T> ? true : false;
321
+ type If<Type extends boolean, IfBranch, ElseBranch> =
322
+ IsNever<Type> extends true
323
+ ? ElseBranch
324
+ : Type extends true
325
+ ? IfBranch
326
+ : ElseBranch;
103
327
 
104
328
  /**
105
- Matches any [primitive value](https://developer.mozilla.org/en-US/docs/Glossary/Primitive).
329
+ Matches any primitive, `void`, `Date`, or `RegExp` value.
330
+ */
331
+ type BuiltIns = Primitive | void | Date | RegExp;
106
332
 
107
- @category Type
333
+ /**
334
+ Test if the given function has multiple call signatures.
335
+
336
+ Needed to handle the case of a single call signature with properties.
337
+
338
+ Multiple call signatures cannot currently be supported due to a TypeScript limitation.
339
+ @see https://github.com/microsoft/TypeScript/issues/29732
108
340
  */
109
- type Primitive =
110
- | null
111
- | undefined
112
- | string
113
- | number
114
- | boolean
115
- | symbol
116
- | bigint;
341
+ type HasMultipleCallSignatures<T extends (...arguments_: any[]) => unknown> =
342
+ T extends {(...arguments_: infer A): unknown; (...arguments_: infer B): unknown}
343
+ ? B extends A
344
+ ? A extends B
345
+ ? false
346
+ : true
347
+ : true
348
+ : false;
117
349
 
118
350
  /**
119
351
  Useful to flatten the type output to improve type hints shown in editors. And also to transform an interface into a type to aide with assignability.
@@ -160,89 +392,21 @@ const literal = {foo: 123, bar: 'hello', baz: 456};
160
392
  const someType: SomeType = literal;
161
393
  const someInterface: SomeInterface = literal;
162
394
 
163
- function fn(object: Record<string, unknown>): void {}
395
+ declare function fn(object: Record<string, unknown>): void;
164
396
 
165
397
  fn(literal); // Good: literal object type is sealed
166
398
  fn(someType); // Good: type is sealed
399
+ // @ts-expect-error
167
400
  fn(someInterface); // Error: Index signature for type 'string' is missing in type 'someInterface'. Because `interface` can be re-opened
168
401
  fn(someInterface as Simplify<SomeInterface>); // Good: transform an `interface` into a `type`
169
402
  ```
170
403
 
171
404
  @link https://github.com/microsoft/TypeScript/issues/15300
172
- @see SimplifyDeep
405
+ @see {@link SimplifyDeep}
173
406
  @category Object
174
407
  */
175
408
  type Simplify<T> = {[KeyType in keyof T]: T[KeyType]} & {};
176
409
 
177
- /**
178
- Extract all optional keys from the given type.
179
-
180
- This is useful when you want to create a new type that contains different type values for the optional keys only.
181
-
182
- @example
183
- ```
184
- import type {OptionalKeysOf, Except} from 'type-fest';
185
-
186
- interface User {
187
- name: string;
188
- surname: string;
189
-
190
- luckyNumber?: number;
191
- }
192
-
193
- const REMOVE_FIELD = Symbol('remove field symbol');
194
- type UpdateOperation<Entity extends object> = Except<Partial<Entity>, OptionalKeysOf<Entity>> & {
195
- [Key in OptionalKeysOf<Entity>]?: Entity[Key] | typeof REMOVE_FIELD;
196
- };
197
-
198
- const update1: UpdateOperation<User> = {
199
- name: 'Alice'
200
- };
201
-
202
- const update2: UpdateOperation<User> = {
203
- name: 'Bob',
204
- luckyNumber: REMOVE_FIELD
205
- };
206
- ```
207
-
208
- @category Utilities
209
- */
210
- type OptionalKeysOf<BaseType extends object> =
211
- BaseType extends unknown // For distributing `BaseType`
212
- ? (keyof {
213
- [Key in keyof BaseType as BaseType extends Record<Key, BaseType[Key]> ? never : Key]: never
214
- }) & (keyof BaseType) // Intersect with `keyof BaseType` to ensure result of `OptionalKeysOf<BaseType>` is always assignable to `keyof BaseType`
215
- : never; // Should never happen
216
-
217
- /**
218
- Extract all required keys from the given type.
219
-
220
- This is useful when you want to create a new type that contains different type values for the required keys only or use the list of keys for validation purposes, etc...
221
-
222
- @example
223
- ```
224
- import type {RequiredKeysOf} from 'type-fest';
225
-
226
- declare function createValidation<Entity extends object, Key extends RequiredKeysOf<Entity> = RequiredKeysOf<Entity>>(field: Key, validator: (value: Entity[Key]) => boolean): ValidatorFn;
227
-
228
- interface User {
229
- name: string;
230
- surname: string;
231
-
232
- luckyNumber?: number;
233
- }
234
-
235
- const validator1 = createValidation<User>('name', value => value.length < 25);
236
- const validator2 = createValidation<User>('surname', value => value.length < 25);
237
- ```
238
-
239
- @category Utilities
240
- */
241
- type RequiredKeysOf<BaseType extends object> =
242
- BaseType extends unknown // For distributing `BaseType`
243
- ? Exclude<keyof BaseType, OptionalKeysOf<BaseType>>
244
- : never; // Should never happen
245
-
246
410
  /**
247
411
  Omit any index signatures from the given object type, leaving only explicitly defined properties.
248
412
 
@@ -260,6 +424,7 @@ It relies on the fact that an empty object (`{}`) is assignable to an object wit
260
424
  ```
261
425
  const indexed: Record<string, unknown> = {}; // Allowed
262
426
 
427
+ // @ts-expect-error
263
428
  const keyed: Record<'foo', unknown> = {}; // Error
264
429
  // => TS2739: Type '{}' is missing the following properties from type 'Record<"foo" | "bar", unknown>': foo, bar
265
430
  ```
@@ -273,16 +438,14 @@ type Indexed = {} extends Record<string, unknown>
273
438
  // => '✅ `{}` is assignable to `Record<string, unknown>`'
274
439
 
275
440
  type Keyed = {} extends Record<'foo' | 'bar', unknown>
276
- ? "✅ `{}` is assignable to `Record<'foo' | 'bar', unknown>`"
277
- : "❌ `{}` is NOT assignable to `Record<'foo' | 'bar', unknown>`";
441
+ ? '✅ `{}` is assignable to `Record<\'foo\' | \'bar\', unknown>`'
442
+ : '❌ `{}` is NOT assignable to `Record<\'foo\' | \'bar\', unknown>`';
278
443
  // => "❌ `{}` is NOT assignable to `Record<'foo' | 'bar', unknown>`"
279
444
  ```
280
445
 
281
446
  Using a [mapped type](https://www.typescriptlang.org/docs/handbook/2/mapped-types.html#further-exploration), you can then check for each `KeyType` of `ObjectType`...
282
447
 
283
448
  ```
284
- import type {OmitIndexSignature} from 'type-fest';
285
-
286
449
  type OmitIndexSignature<ObjectType> = {
287
450
  [KeyType in keyof ObjectType // Map each key of `ObjectType`...
288
451
  ]: ObjectType[KeyType]; // ...to its original value, i.e. `OmitIndexSignature<Foo> == Foo`.
@@ -292,14 +455,12 @@ type OmitIndexSignature<ObjectType> = {
292
455
  ...whether an empty object (`{}`) would be assignable to an object with that `KeyType` (`Record<KeyType, unknown>`)...
293
456
 
294
457
  ```
295
- import type {OmitIndexSignature} from 'type-fest';
296
-
297
458
  type OmitIndexSignature<ObjectType> = {
298
459
  [KeyType in keyof ObjectType
299
- // Is `{}` assignable to `Record<KeyType, unknown>`?
300
- as {} extends Record<KeyType, unknown>
301
- ? ... // ✅ `{}` is assignable to `Record<KeyType, unknown>`
302
- : ... // ❌ `{}` is NOT assignable to `Record<KeyType, unknown>`
460
+ // Is `{}` assignable to `Record<KeyType, unknown>`?
461
+ as {} extends Record<KeyType, unknown>
462
+ ? never // ✅ `{}` is assignable to `Record<KeyType, unknown>`
463
+ : KeyType // ❌ `{}` is NOT assignable to `Record<KeyType, unknown>`
303
464
  ]: ObjectType[KeyType];
304
465
  };
305
466
  ```
@@ -310,27 +471,27 @@ If `{}` is assignable, it means that `KeyType` is an index signature and we want
310
471
  ```
311
472
  import type {OmitIndexSignature} from 'type-fest';
312
473
 
313
- interface Example {
474
+ type Example = {
314
475
  // These index signatures will be removed.
315
- [x: string]: any
316
- [x: number]: any
317
- [x: symbol]: any
318
- [x: `head-${string}`]: string
319
- [x: `${string}-tail`]: string
320
- [x: `head-${string}-tail`]: string
321
- [x: `${bigint}`]: string
322
- [x: `embedded-${number}`]: string
476
+ [x: string]: any;
477
+ [x: number]: any;
478
+ [x: symbol]: any;
479
+ [x: `head-${string}`]: string;
480
+ [x: `${string}-tail`]: string;
481
+ [x: `head-${string}-tail`]: string;
482
+ [x: `${bigint}`]: string;
483
+ [x: `embedded-${number}`]: string;
323
484
 
324
485
  // These explicitly defined keys will remain.
325
486
  foo: 'bar';
326
487
  qux?: 'baz';
327
- }
488
+ };
328
489
 
329
490
  type ExampleWithoutIndexSignatures = OmitIndexSignature<Example>;
330
491
  // => { foo: 'bar'; qux?: 'baz' | undefined; }
331
492
  ```
332
493
 
333
- @see PickIndexSignature
494
+ @see {@link PickIndexSignature}
334
495
  @category Object
335
496
  */
336
497
  type OmitIndexSignature<ObjectType> = {
@@ -381,7 +542,7 @@ type ExampleIndexSignature = PickIndexSignature<Example>;
381
542
  // }
382
543
  ```
383
544
 
384
- @see OmitIndexSignature
545
+ @see {@link OmitIndexSignature}
385
546
  @category Object
386
547
  */
387
548
  type PickIndexSignature<ObjectType> = {
@@ -402,12 +563,12 @@ Merge two types into a new type. Keys of the second type overrides keys of the f
402
563
  ```
403
564
  import type {Merge} from 'type-fest';
404
565
 
405
- interface Foo {
566
+ type Foo = {
406
567
  [x: string]: unknown;
407
568
  [x: number]: unknown;
408
569
  foo: string;
409
570
  bar: symbol;
410
- }
571
+ };
411
572
 
412
573
  type Bar = {
413
574
  [x: number]: number;
@@ -431,38 +592,10 @@ export type FooBar = Merge<Foo, Bar>;
431
592
  */
432
593
  type Merge<Destination, Source> =
433
594
  Simplify<
434
- SimpleMerge<PickIndexSignature<Destination>, PickIndexSignature<Source>>
435
- & SimpleMerge<OmitIndexSignature<Destination>, OmitIndexSignature<Source>>
595
+ SimpleMerge<PickIndexSignature<Destination>, PickIndexSignature<Source>>
596
+ & SimpleMerge<OmitIndexSignature<Destination>, OmitIndexSignature<Source>>
436
597
  >;
437
598
 
438
- /**
439
- An if-else-like type that resolves depending on whether the given type is `any`.
440
-
441
- @see {@link IsAny}
442
-
443
- @example
444
- ```
445
- import type {IfAny} from 'type-fest';
446
-
447
- type ShouldBeTrue = IfAny<any>;
448
- //=> true
449
-
450
- type ShouldBeBar = IfAny<'not any', 'foo', 'bar'>;
451
- //=> 'bar'
452
- ```
453
-
454
- @category Type Guard
455
- @category Utilities
456
- */
457
- type IfAny<T, TypeIfAny = true, TypeIfNotAny = false> = (
458
- IsAny<T> extends true ? TypeIfAny : TypeIfNotAny
459
- );
460
-
461
- /**
462
- Matches any primitive, `void`, `Date`, or `RegExp` value.
463
- */
464
- type BuiltIns = Primitive | void | Date | RegExp;
465
-
466
599
  /**
467
600
  Merges user specified options with default options.
468
601
 
@@ -520,18 +653,13 @@ type ApplyDefaultOptions<
520
653
  Defaults extends Simplify<Omit<Required<Options>, RequiredKeysOf<Options>> & Partial<Record<RequiredKeysOf<Options>, never>>>,
521
654
  SpecifiedOptions extends Options,
522
655
  > =
523
- IfAny<SpecifiedOptions, Defaults,
524
- IfNever<SpecifiedOptions, Defaults,
525
- Simplify<Merge<Defaults, {
526
- [Key in keyof SpecifiedOptions
527
- as Key extends OptionalKeysOf<Options>
528
- ? Extract<SpecifiedOptions[Key], undefined> extends never
529
- ? Key
530
- : never
531
- : Key
532
- ]: SpecifiedOptions[Key]
533
- }> & Required<Options>> // `& Required<Options>` ensures that `ApplyDefaultOptions<SomeOption, ...>` is always assignable to `Required<SomeOption>`
534
- >>;
656
+ If<IsAny<SpecifiedOptions>, Defaults,
657
+ If<IsNever<SpecifiedOptions>, Defaults,
658
+ Simplify<Merge<Defaults, {
659
+ [Key in keyof SpecifiedOptions
660
+ as Key extends OptionalKeysOf<Options> ? undefined extends SpecifiedOptions[Key] ? never : Key : Key
661
+ ]: SpecifiedOptions[Key]
662
+ }> & Required<Options>>>>;
535
663
 
536
664
  /**
537
665
  @see {@link PartialDeep}
@@ -550,10 +678,10 @@ type PartialDeepOptions = {
550
678
  - When set to `true`, elements of non-tuple arrays can be `undefined`.
551
679
  - When set to `false`, only explicitly defined elements are allowed in non-tuple arrays, ensuring stricter type checking.
552
680
 
553
- @default true
681
+ @default false
554
682
 
555
683
  @example
556
- You can prevent `undefined` values in non-tuple arrays by passing `{recurseIntoArrays: true; allowUndefinedInNonTupleArrays: false}` as the second type argument:
684
+ You can allow `undefined` values in non-tuple arrays by passing `{recurseIntoArrays: true; allowUndefinedInNonTupleArrays: true}` as the second type argument:
557
685
 
558
686
  ```
559
687
  import type {PartialDeep} from 'type-fest';
@@ -562,10 +690,9 @@ type PartialDeepOptions = {
562
690
  languages: string[];
563
691
  };
564
692
 
565
- declare const partialSettings: PartialDeep<Settings, {recurseIntoArrays: true; allowUndefinedInNonTupleArrays: false}>;
693
+ declare const partialSettings: PartialDeep<Settings, {recurseIntoArrays: true; allowUndefinedInNonTupleArrays: true}>;
566
694
 
567
- partialSettings.languages = [undefined]; // Error
568
- partialSettings.languages = []; // Ok
695
+ partialSettings.languages = [undefined]; // OK
569
696
  ```
570
697
  */
571
698
  readonly allowUndefinedInNonTupleArrays?: boolean;
@@ -573,7 +700,7 @@ type PartialDeepOptions = {
573
700
 
574
701
  type DefaultPartialDeepOptions = {
575
702
  recurseIntoArrays: false;
576
- allowUndefinedInNonTupleArrays: true;
703
+ allowUndefinedInNonTupleArrays: false;
577
704
  };
578
705
 
579
706
  /**
@@ -587,19 +714,19 @@ Use-cases:
587
714
  ```
588
715
  import type {PartialDeep} from 'type-fest';
589
716
 
590
- const settings: Settings = {
717
+ let settings = {
591
718
  textEditor: {
592
719
  fontSize: 14,
593
720
  fontColor: '#000000',
594
- fontWeight: 400
721
+ fontWeight: 400,
595
722
  },
596
723
  autocomplete: false,
597
- autosave: true
724
+ autosave: true,
598
725
  };
599
726
 
600
- const applySavedSettings = (savedSettings: PartialDeep<Settings>) => {
601
- return {...settings, ...savedSettings};
602
- }
727
+ const applySavedSettings = (savedSettings: PartialDeep<typeof settings>) => (
728
+ {...settings, ...savedSettings, textEditor: {...settings.textEditor, ...savedSettings.textEditor}}
729
+ );
603
730
 
604
731
  settings = applySavedSettings({textEditor: {fontWeight: 500}});
605
732
  ```
@@ -609,13 +736,15 @@ By default, this does not affect elements in array and tuple types. You can chan
609
736
  ```
610
737
  import type {PartialDeep} from 'type-fest';
611
738
 
612
- type Settings = {
613
- languages: string[];
614
- }
739
+ type Shape = {
740
+ dimensions: [number, number];
741
+ };
615
742
 
616
- const partialSettings: PartialDeep<Settings, {recurseIntoArrays: true}> = {
617
- languages: [undefined]
743
+ const partialShape: PartialDeep<Shape, {recurseIntoArrays: true}> = {
744
+ dimensions: [], // OK
618
745
  };
746
+
747
+ partialShape.dimensions = [15]; // OK
619
748
  ```
620
749
 
621
750
  @see {@link PartialDeepOptions}
@@ -630,16 +759,20 @@ type PartialDeep<T, Options extends PartialDeepOptions = {}> =
630
759
 
631
760
  type _PartialDeep<T, Options extends Required<PartialDeepOptions>> = T extends BuiltIns | ((new (...arguments_: any[]) => unknown))
632
761
  ? T
633
- : IsNever<keyof T> extends true // For functions with no properties
634
- ? T
635
- : T extends Map<infer KeyType, infer ValueType>
636
- ? PartialMapDeep<KeyType, ValueType, Options>
637
- : T extends Set<infer ItemType>
638
- ? PartialSetDeep<ItemType, Options>
639
- : T extends ReadonlyMap<infer KeyType, infer ValueType>
640
- ? PartialReadonlyMapDeep<KeyType, ValueType, Options>
641
- : T extends ReadonlySet<infer ItemType>
642
- ? PartialReadonlySetDeep<ItemType, Options>
762
+ : T extends Map<infer KeyType, infer ValueType>
763
+ ? PartialMapDeep<KeyType, ValueType, Options>
764
+ : T extends Set<infer ItemType>
765
+ ? PartialSetDeep<ItemType, Options>
766
+ : T extends ReadonlyMap<infer KeyType, infer ValueType>
767
+ ? PartialReadonlyMapDeep<KeyType, ValueType, Options>
768
+ : T extends ReadonlySet<infer ItemType>
769
+ ? PartialReadonlySetDeep<ItemType, Options>
770
+ : T extends (...arguments_: any[]) => unknown
771
+ ? IsNever<keyof T> extends true
772
+ ? T // For functions with no properties
773
+ : HasMultipleCallSignatures<T> extends true
774
+ ? T
775
+ : ((...arguments_: Parameters<T>) => ReturnType<T>) & PartialObjectDeep<T, Options>
643
776
  : T extends object
644
777
  ? T extends ReadonlyArray<infer ItemType> // Test for arrays/tuples, per https://github.com/microsoft/TypeScript/issues/35156
645
778
  ? Options['recurseIntoArrays'] extends true
@@ -675,15 +808,12 @@ type PartialReadonlySetDeep<T, Options extends Required<PartialDeepOptions>> = {
675
808
  /**
676
809
  Same as `PartialDeep`, but accepts only `object`s as inputs. Internal helper for `PartialDeep`.
677
810
  */
678
- type PartialObjectDeep<ObjectType extends object, Options extends Required<PartialDeepOptions>> =
679
- (ObjectType extends (...arguments_: any) => unknown
680
- ? (...arguments_: Parameters<ObjectType>) => ReturnType<ObjectType>
681
- : {}) & ({
682
- [KeyType in keyof ObjectType]?: _PartialDeep<ObjectType[KeyType], Options>
683
- });
811
+ type PartialObjectDeep<ObjectType extends object, Options extends Required<PartialDeepOptions>> = {
812
+ [KeyType in keyof ObjectType]?: _PartialDeep<ObjectType[KeyType], Options>
813
+ };
684
814
 
685
815
  interface StreamObjectOnFinishResult<T extends Schema> {
686
- object?: Infer<T>;
816
+ object?: Schema.InferOutput<T>;
687
817
  }
688
818
  interface StreamObjectOptions<T extends Schema> extends StreamTextOptions {
689
819
  schema: T;
@@ -693,24 +823,24 @@ interface StreamObjectOptions<T extends Schema> extends StreamTextOptions {
693
823
  strict?: boolean;
694
824
  }
695
825
  interface StreamObjectResult<T extends Schema> extends StreamTextResult {
696
- elementStream?: ReadableStream<Infer<T>>;
697
- partialObjectStream?: ReadableStream<PartialDeep<Infer<T>>>;
826
+ elementStream?: ReadableStream<Schema.InferOutput<T>>;
827
+ partialObjectStream?: ReadableStream<PartialDeep<Schema.InferOutput<T>>>;
698
828
  }
699
829
  declare function streamObject<T extends Schema>(options: StreamObjectOptions<T> & {
700
830
  output: 'array';
701
831
  }): Promise<StreamObjectResult<T> & {
702
- elementStream: ReadableStream<Infer<T>>;
832
+ elementStream: ReadableStream<Schema.InferOutput<T>>;
703
833
  partialObjectStream: undefined;
704
834
  }>;
705
835
  declare function streamObject<T extends Schema>(options: StreamObjectOptions<T> & {
706
836
  output: 'object';
707
837
  }): Promise<StreamObjectResult<T> & {
708
838
  elementStream: undefined;
709
- partialObjectStream: ReadableStream<PartialDeep<Infer<T>>>;
839
+ partialObjectStream: ReadableStream<PartialDeep<Schema.InferOutput<T>>>;
710
840
  }>;
711
841
  declare function streamObject<T extends Schema>(options: StreamObjectOptions<T>): Promise<StreamObjectResult<T> & {
712
842
  elementStream: undefined;
713
- partialObjectStream: ReadableStream<PartialDeep<Infer<T>>>;
843
+ partialObjectStream: ReadableStream<PartialDeep<Schema.InferOutput<T>>>;
714
844
  }>;
715
845
 
716
846
  declare const toElementStream: <T>(stream: ReadableStream<string>) => ReadableStream<T>;
package/dist/index.js CHANGED
@@ -19,23 +19,23 @@ var hasRequiredParse;
19
19
  function requireParse () {
20
20
  if (hasRequiredParse) return parse;
21
21
  hasRequiredParse = 1;
22
- (function (exports) {
23
- Object.defineProperty(exports, "__esModule", { value: true });
24
- exports.parse = exports.enableErrorLogging = exports.disableErrorLogging = exports.setErrorLogger = void 0;
22
+ (function (exports$1) {
23
+ Object.defineProperty(exports$1, "__esModule", { value: true });
24
+ exports$1.parse = exports$1.enableErrorLogging = exports$1.disableErrorLogging = exports$1.setErrorLogger = void 0;
25
25
  let logError = console.error;
26
26
  function setErrorLogger(logger) {
27
27
  logError = logger;
28
28
  }
29
- exports.setErrorLogger = setErrorLogger;
29
+ exports$1.setErrorLogger = setErrorLogger;
30
30
  function disableErrorLogging() {
31
31
  logError = () => {
32
32
  };
33
33
  }
34
- exports.disableErrorLogging = disableErrorLogging;
34
+ exports$1.disableErrorLogging = disableErrorLogging;
35
35
  function enableErrorLogging() {
36
36
  logError = console.error;
37
37
  }
38
- exports.enableErrorLogging = enableErrorLogging;
38
+ exports$1.enableErrorLogging = enableErrorLogging;
39
39
  function parse(s) {
40
40
  if (s === void 0) {
41
41
  return void 0;
@@ -62,7 +62,7 @@ function requireParse () {
62
62
  return data;
63
63
  }
64
64
  }
65
- exports.parse = parse;
65
+ exports$1.parse = parse;
66
66
  (function(parse2) {
67
67
  parse2.onExtraToken = (text, data, reminding) => {
68
68
  logError("parsed json with extra tokens:", {
@@ -71,7 +71,7 @@ function requireParse () {
71
71
  reminding
72
72
  });
73
73
  };
74
- })(parse = exports.parse || (exports.parse = {}));
74
+ })(parse = exports$1.parse || (exports$1.parse = {}));
75
75
  function parseAny(s, e, fallback) {
76
76
  const parser = parsers[s[0]] || fallback;
77
77
  if (!parser) {
package/package.json CHANGED
@@ -1,7 +1,7 @@
1
1
  {
2
2
  "name": "@xsai/stream-object",
3
3
  "type": "module",
4
- "version": "0.4.0-beta.9",
4
+ "version": "0.4.0",
5
5
  "description": "extra-small AI SDK.",
6
6
  "author": "Moeru AI",
7
7
  "license": "MIT",
@@ -29,13 +29,13 @@
29
29
  "dist"
30
30
  ],
31
31
  "dependencies": {
32
- "@xsai/stream-text": "~0.4.0-beta.9",
33
- "xsschema": "~0.4.0-beta.9"
32
+ "@xsai/stream-text": "~0.4.0",
33
+ "xsschema": "~0.4.0"
34
34
  },
35
35
  "devDependencies": {
36
36
  "@valibot/to-json-schema": "^1.0.0",
37
- "best-effort-json-parser": "^1.1.3",
38
- "type-fest": "^4.41.0",
37
+ "best-effort-json-parser": "^1.2.1",
38
+ "type-fest": "^5.3.1",
39
39
  "valibot": "^1.0.0"
40
40
  },
41
41
  "scripts": {