@fluidframework/core-interfaces 2.90.0 → 2.91.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/CHANGELOG.md +4 -0
- package/dist/exposedInternalUtilityTypes.d.ts.map +1 -1
- package/dist/exposedInternalUtilityTypes.js.map +1 -1
- package/lib/exposedInternalUtilityTypes.d.ts.map +1 -1
- package/lib/exposedInternalUtilityTypes.js.map +1 -1
- package/package.json +3 -3
- package/src/exposedInternalUtilityTypes.ts +536 -513
|
@@ -134,20 +134,18 @@ export namespace InternalUtilityTypes {
|
|
|
134
134
|
*
|
|
135
135
|
* @system
|
|
136
136
|
*/
|
|
137
|
-
export type OptionalNonSymbolKeysOf<
|
|
138
|
-
|
|
139
|
-
|
|
140
|
-
|
|
141
|
-
|
|
142
|
-
|
|
143
|
-
|
|
144
|
-
|
|
145
|
-
|
|
146
|
-
|
|
147
|
-
|
|
148
|
-
|
|
149
|
-
IfSameType<Keys, Result, Keys, Extract<Result, string | number>>
|
|
150
|
-
: never;
|
|
137
|
+
export type OptionalNonSymbolKeysOf<T extends object, Keys extends keyof T = keyof T> =
|
|
138
|
+
Exclude<
|
|
139
|
+
{
|
|
140
|
+
[K in Keys]: T extends Record<K, T[K]> ? never : K;
|
|
141
|
+
}[Keys],
|
|
142
|
+
undefined | symbol
|
|
143
|
+
> extends infer Result
|
|
144
|
+
? // Workaround for TypeScript bug/limitation where an alias for a type
|
|
145
|
+
// is not considered the same type when used as an index. This restores
|
|
146
|
+
// the original `Keys` (`keyof T`) type when there is no filtering.
|
|
147
|
+
IfSameType<Keys, Result, Keys, Extract<Result, string | number>>
|
|
148
|
+
: never;
|
|
151
149
|
|
|
152
150
|
/**
|
|
153
151
|
* Returns non-symbol keys for required properties of an object type.
|
|
@@ -158,20 +156,18 @@ export namespace InternalUtilityTypes {
|
|
|
158
156
|
*
|
|
159
157
|
* @system
|
|
160
158
|
*/
|
|
161
|
-
export type RequiredNonSymbolKeysOf<
|
|
162
|
-
|
|
163
|
-
|
|
164
|
-
|
|
165
|
-
|
|
166
|
-
|
|
167
|
-
|
|
168
|
-
|
|
169
|
-
|
|
170
|
-
|
|
171
|
-
|
|
172
|
-
|
|
173
|
-
IfSameType<Keys, Result, Keys, Extract<Result, string | number>>
|
|
174
|
-
: never;
|
|
159
|
+
export type RequiredNonSymbolKeysOf<T extends object, Keys extends keyof T = keyof T> =
|
|
160
|
+
Exclude<
|
|
161
|
+
{
|
|
162
|
+
[K in Keys]: T extends Record<K, T[K]> ? K : never;
|
|
163
|
+
}[Keys],
|
|
164
|
+
undefined | symbol
|
|
165
|
+
> extends infer Result
|
|
166
|
+
? // Workaround for TypeScript bug/limitation where an alias for a type
|
|
167
|
+
// is not considered the same type when used as an index. This restores
|
|
168
|
+
// the original `Keys` (`keyof T`) type when there is no filtering.
|
|
169
|
+
IfSameType<Keys, Result, Keys, Extract<Result, string | number>>
|
|
170
|
+
: never;
|
|
175
171
|
|
|
176
172
|
/**
|
|
177
173
|
* Returns Result.WhenSomethingDeserializable if T is sometimes at least a
|
|
@@ -289,58 +285,59 @@ export namespace InternalUtilityTypes {
|
|
|
289
285
|
TExactExceptions extends unknown[],
|
|
290
286
|
TExtendsException,
|
|
291
287
|
Keys extends keyof T = keyof T,
|
|
292
|
-
> =
|
|
293
|
-
|
|
294
|
-
|
|
295
|
-
|
|
296
|
-
|
|
297
|
-
|
|
298
|
-
|
|
299
|
-
|
|
300
|
-
|
|
301
|
-
unknown,
|
|
302
|
-
/* value might not be supported => check for indexed key */ IfIndexOrBrandedKey<
|
|
303
|
-
K,
|
|
304
|
-
/* indexed => allow K */ K,
|
|
305
|
-
/* literal => exclude K */ never
|
|
306
|
-
>,
|
|
307
|
-
/* extract types that might lead to missing property */ Extract<
|
|
288
|
+
> =
|
|
289
|
+
Exclude<
|
|
290
|
+
{
|
|
291
|
+
[K in Keys]: /* all possible types that aren't already allowed, with the exception of `unknown` */
|
|
292
|
+
ExcludeExactlyInTuple<
|
|
293
|
+
Exclude<T[K], TExtendsException>,
|
|
294
|
+
OmitExactlyFromTuple<TExactExceptions, unknown>
|
|
295
|
+
> extends infer PossibleTypeLessAllowed
|
|
296
|
+
? IfSameType<
|
|
308
297
|
PossibleTypeLessAllowed,
|
|
309
|
-
|
|
310
|
-
|
|
311
|
-
|
|
312
|
-
|
|
313
|
-
|
|
314
|
-
|
|
315
|
-
|
|
316
|
-
|
|
317
|
-
|
|
318
|
-
|
|
319
|
-
|
|
320
|
-
|
|
321
|
-
|
|
322
|
-
|
|
323
|
-
|
|
324
|
-
|
|
325
|
-
|
|
326
|
-
|
|
327
|
-
|
|
328
|
-
|
|
329
|
-
|
|
330
|
-
|
|
331
|
-
|
|
332
|
-
|
|
333
|
-
|
|
334
|
-
|
|
335
|
-
|
|
336
|
-
|
|
337
|
-
|
|
338
|
-
|
|
339
|
-
|
|
340
|
-
|
|
341
|
-
|
|
342
|
-
|
|
343
|
-
|
|
298
|
+
unknown,
|
|
299
|
+
/* value might not be supported => check for indexed key */ IfIndexOrBrandedKey<
|
|
300
|
+
K,
|
|
301
|
+
/* indexed => allow K */ K,
|
|
302
|
+
/* literal => exclude K */ never
|
|
303
|
+
>,
|
|
304
|
+
/* extract types that might lead to missing property */ Extract<
|
|
305
|
+
PossibleTypeLessAllowed,
|
|
306
|
+
/* types that might lead to missing property, except `bigint` */
|
|
307
|
+
// eslint-disable-next-line @typescript-eslint/no-unsafe-function-type
|
|
308
|
+
undefined | symbol | Function
|
|
309
|
+
> extends never
|
|
310
|
+
? /* all types are supported plus possibly `bigint` => */
|
|
311
|
+
/* check for only `bigint` remaining */ IfSameType<
|
|
312
|
+
PossibleTypeLessAllowed,
|
|
313
|
+
bigint,
|
|
314
|
+
/* only `bigint` => nothing supported */ never,
|
|
315
|
+
/* exclusively supported types (and maybe `bigint`) or exactly `never` */
|
|
316
|
+
/* => check for `never` */ T[K] extends never ? never : K
|
|
317
|
+
>
|
|
318
|
+
: /* value might not be supported => check for any supported */ TestDeserializabilityOf<
|
|
319
|
+
T[K],
|
|
320
|
+
OmitExactlyFromTuple<TExactExceptions, unknown>,
|
|
321
|
+
TExtendsException,
|
|
322
|
+
{
|
|
323
|
+
WhenSomethingDeserializable: /* => check for indexed key */ IfIndexOrBrandedKey<
|
|
324
|
+
K,
|
|
325
|
+
/* indexed => allow K */ K,
|
|
326
|
+
/* literal => exclude K */ never
|
|
327
|
+
>;
|
|
328
|
+
WhenNeverDeserializable: /* => exclude K */ never;
|
|
329
|
+
}
|
|
330
|
+
>
|
|
331
|
+
>
|
|
332
|
+
: never;
|
|
333
|
+
}[Keys],
|
|
334
|
+
undefined | symbol
|
|
335
|
+
> extends infer Result
|
|
336
|
+
? // Workaround for TypeScript bug/limitation where an alias for a type
|
|
337
|
+
// is not considered the same type when used as an index. This restores
|
|
338
|
+
// the original `Keys` (`keyof T`) type when there is no filtering.
|
|
339
|
+
IfSameType<Keys, Result, Keys, Extract<Result, string | number>>
|
|
340
|
+
: never;
|
|
344
341
|
|
|
345
342
|
/**
|
|
346
343
|
* Returns non-symbol, literal keys for partially supported properties of an object type.
|
|
@@ -357,43 +354,49 @@ export namespace InternalUtilityTypes {
|
|
|
357
354
|
TExactExceptions extends unknown[],
|
|
358
355
|
TExtendsException,
|
|
359
356
|
Keys extends keyof T = keyof T,
|
|
360
|
-
> =
|
|
361
|
-
|
|
362
|
-
|
|
363
|
-
K
|
|
364
|
-
|
|
365
|
-
|
|
366
|
-
|
|
367
|
-
|
|
368
|
-
|
|
369
|
-
|
|
370
|
-
|
|
371
|
-
|
|
372
|
-
|
|
373
|
-
|
|
374
|
-
|
|
375
|
-
|
|
376
|
-
|
|
377
|
-
|
|
378
|
-
|
|
379
|
-
|
|
380
|
-
|
|
381
|
-
|
|
382
|
-
|
|
383
|
-
|
|
384
|
-
|
|
385
|
-
|
|
386
|
-
|
|
387
|
-
|
|
388
|
-
|
|
389
|
-
|
|
390
|
-
|
|
391
|
-
|
|
392
|
-
|
|
393
|
-
|
|
394
|
-
|
|
395
|
-
|
|
396
|
-
|
|
357
|
+
> =
|
|
358
|
+
Exclude<
|
|
359
|
+
{
|
|
360
|
+
[K in Keys]: IfIndexOrBrandedKey<
|
|
361
|
+
K,
|
|
362
|
+
/* indexed => exclude K */ never,
|
|
363
|
+
/* literal => ... */
|
|
364
|
+
/* all possible types that aren't already allowed, with the exception of `unknown` */
|
|
365
|
+
ExcludeExactlyInTuple<
|
|
366
|
+
Exclude<T[K], TExtendsException>,
|
|
367
|
+
OmitExactlyFromTuple<TExactExceptions, unknown>
|
|
368
|
+
> extends infer PossibleTypeLessAllowed
|
|
369
|
+
? Extract<
|
|
370
|
+
IfSameType<
|
|
371
|
+
PossibleTypeLessAllowed,
|
|
372
|
+
unknown,
|
|
373
|
+
undefined,
|
|
374
|
+
PossibleTypeLessAllowed
|
|
375
|
+
>,
|
|
376
|
+
/* types that might lead to missing property */
|
|
377
|
+
// eslint-disable-next-line @typescript-eslint/no-unsafe-function-type
|
|
378
|
+
undefined | symbol | Function
|
|
379
|
+
> extends never
|
|
380
|
+
? /* exclusively supported types or exactly `never` */ never
|
|
381
|
+
: /* at least some unsupported type => check for any supported */ TestDeserializabilityOf<
|
|
382
|
+
T[K],
|
|
383
|
+
OmitExactlyFromTuple<TExactExceptions, unknown>,
|
|
384
|
+
TExtendsException,
|
|
385
|
+
{
|
|
386
|
+
WhenSomethingDeserializable: K;
|
|
387
|
+
WhenNeverDeserializable: never;
|
|
388
|
+
}
|
|
389
|
+
>
|
|
390
|
+
: never
|
|
391
|
+
>;
|
|
392
|
+
}[Keys],
|
|
393
|
+
undefined | symbol
|
|
394
|
+
> extends infer Result
|
|
395
|
+
? // Workaround for TypeScript bug/limitation where an alias for a type
|
|
396
|
+
// is not considered the same type when used as an index. This restores
|
|
397
|
+
// the original `Keys` (`keyof T`) type when there is no filtering.
|
|
398
|
+
IfSameType<Keys, Result, Keys, Extract<Result, string | number>>
|
|
399
|
+
: never;
|
|
397
400
|
|
|
398
401
|
/**
|
|
399
402
|
* Filters a type `T` for `undefined` that is not viable in an array (or tuple) that
|
|
@@ -408,32 +411,33 @@ export namespace InternalUtilityTypes {
|
|
|
408
411
|
Controls extends FilterControls,
|
|
409
412
|
TAncestorTypes extends unknown[],
|
|
410
413
|
TBlessed,
|
|
411
|
-
> =
|
|
412
|
-
|
|
413
|
-
|
|
414
|
-
|
|
415
|
-
|
|
416
|
-
|
|
417
|
-
|
|
418
|
-
|
|
419
|
-
|
|
420
|
-
|
|
421
|
-
|
|
422
|
-
|
|
423
|
-
|
|
424
|
-
|
|
425
|
-
|
|
426
|
-
|
|
427
|
-
|
|
428
|
-
|
|
429
|
-
|
|
430
|
-
|
|
431
|
-
|
|
432
|
-
|
|
433
|
-
|
|
434
|
-
|
|
435
|
-
|
|
436
|
-
|
|
414
|
+
> =
|
|
415
|
+
/* Some initial filtering must be provided before a test for undefined. */
|
|
416
|
+
/* These tests are expected to match those in JsonSerializableImpl. */
|
|
417
|
+
/* test for 'any' */ boolean extends (T extends never ? true : false)
|
|
418
|
+
? /* 'any' => */ TBlessed
|
|
419
|
+
: /* test for 'unknown' */ unknown extends T
|
|
420
|
+
? /* 'unknown' => */ TBlessed
|
|
421
|
+
: /* test for exact recursion */ IfExactTypeInTuple<
|
|
422
|
+
T,
|
|
423
|
+
TAncestorTypes,
|
|
424
|
+
/* recursion; stop here => */ T,
|
|
425
|
+
/* test for JSON primitive types or given alternative */ T extends
|
|
426
|
+
| null
|
|
427
|
+
| boolean
|
|
428
|
+
| number
|
|
429
|
+
| string
|
|
430
|
+
| Controls["AllowExtensionOf"]
|
|
431
|
+
? /* primitive types or alternative => */ T
|
|
432
|
+
: /* test for exact alternative */ IfExactTypeInTuple<
|
|
433
|
+
T,
|
|
434
|
+
Controls["AllowExactly"],
|
|
435
|
+
T,
|
|
436
|
+
/* test for undefined possibility */ undefined extends T
|
|
437
|
+
? /* undefined | ... => */ SerializationErrorPerUndefinedArrayElement
|
|
438
|
+
: TBlessed
|
|
439
|
+
>
|
|
440
|
+
>;
|
|
437
441
|
|
|
438
442
|
/**
|
|
439
443
|
* Filters a type `T` for types that become null through JSON serialization.
|
|
@@ -444,34 +448,35 @@ export namespace InternalUtilityTypes {
|
|
|
444
448
|
T,
|
|
445
449
|
Controls extends DeserializedFilterControls,
|
|
446
450
|
TBlessed,
|
|
447
|
-
> =
|
|
448
|
-
|
|
449
|
-
|
|
450
|
-
|
|
451
|
-
|
|
452
|
-
|
|
453
|
-
|
|
454
|
-
|
|
455
|
-
|
|
456
|
-
|
|
457
|
-
|
|
458
|
-
|
|
459
|
-
|
|
460
|
-
|
|
461
|
-
|
|
462
|
-
|
|
463
|
-
|
|
464
|
-
|
|
465
|
-
|
|
466
|
-
|
|
467
|
-
|
|
468
|
-
|
|
469
|
-
|
|
470
|
-
|
|
471
|
-
|
|
472
|
-
|
|
473
|
-
|
|
474
|
-
|
|
451
|
+
> =
|
|
452
|
+
/* Some initial filtering must be provided before a test for undefined, symbol, or function. */
|
|
453
|
+
/* These tests are expected to match those in JsonDeserializedImpl. */
|
|
454
|
+
/* test for 'any' */ boolean extends (T extends never ? true : false)
|
|
455
|
+
? /* 'any' => */ TBlessed
|
|
456
|
+
: /* test for 'unknown' */ unknown extends T
|
|
457
|
+
? /* 'unknown' => */ TBlessed
|
|
458
|
+
: /* test for JSON primitive types or general alternative */ T extends
|
|
459
|
+
| null
|
|
460
|
+
| boolean
|
|
461
|
+
| number
|
|
462
|
+
| string
|
|
463
|
+
| Controls["AllowExtensionOf"]
|
|
464
|
+
? /* primitive or replaced types => */ T
|
|
465
|
+
: /* test for exact alternative */ IfExactTypeInTuple<
|
|
466
|
+
T,
|
|
467
|
+
[...Controls["AllowExactly"], Controls["RecursionMarkerAllowed"]],
|
|
468
|
+
/* exactly replaced => */ T,
|
|
469
|
+
/* test for known types that become null */ T extends undefined | symbol
|
|
470
|
+
? /* => */ null
|
|
471
|
+
: // eslint-disable-next-line @typescript-eslint/no-unsafe-function-type
|
|
472
|
+
T extends Function
|
|
473
|
+
? ExtractFunctionFromIntersection<T> extends {
|
|
474
|
+
classification: "exactly Function";
|
|
475
|
+
}
|
|
476
|
+
? null
|
|
477
|
+
: null | TBlessed
|
|
478
|
+
: TBlessed
|
|
479
|
+
>;
|
|
475
480
|
|
|
476
481
|
/**
|
|
477
482
|
* Checks for a type that is simple class of number and string indexed types to numbers and strings.
|
|
@@ -515,11 +520,8 @@ export namespace InternalUtilityTypes {
|
|
|
515
520
|
*
|
|
516
521
|
* @system
|
|
517
522
|
*/
|
|
518
|
-
export type IfSameType<X, Y, IfSame = unknown, IfDifferent = never> =
|
|
519
|
-
? 1
|
|
520
|
-
: 2) extends <T>() => T extends Y ? 1 : 2
|
|
521
|
-
? IfSame
|
|
522
|
-
: IfDifferent;
|
|
523
|
+
export type IfSameType<X, Y, IfSame = unknown, IfDifferent = never> =
|
|
524
|
+
(<T>() => T extends X ? 1 : 2) extends <T>() => T extends Y ? 1 : 2 ? IfSame : IfDifferent;
|
|
523
525
|
|
|
524
526
|
/**
|
|
525
527
|
* Test for type equality with tuple of other types.
|
|
@@ -701,17 +703,15 @@ export namespace InternalUtilityTypes {
|
|
|
701
703
|
*
|
|
702
704
|
* @system
|
|
703
705
|
*/
|
|
704
|
-
export type FilterPreservingFunction<
|
|
705
|
-
Original extends
|
|
706
|
-
|
|
707
|
-
|
|
708
|
-
|
|
709
|
-
|
|
710
|
-
|
|
711
|
-
|
|
712
|
-
|
|
713
|
-
: TFunction & Filtered
|
|
714
|
-
: never;
|
|
706
|
+
export type FilterPreservingFunction<Original extends object, Filtered> =
|
|
707
|
+
ExtractFunctionFromIntersection<Original> extends {
|
|
708
|
+
classification: infer TClassification;
|
|
709
|
+
function: infer TFunction;
|
|
710
|
+
}
|
|
711
|
+
? TClassification extends "exactly Function"
|
|
712
|
+
? TFunction
|
|
713
|
+
: TFunction & Filtered
|
|
714
|
+
: never;
|
|
715
715
|
|
|
716
716
|
/**
|
|
717
717
|
* Replaces any instance where a type T recurses into itself or a portion of
|
|
@@ -745,36 +745,37 @@ export namespace InternalUtilityTypes {
|
|
|
745
745
|
Controls extends FilterControls,
|
|
746
746
|
TAncestorTypes extends unknown[] = [],
|
|
747
747
|
TNextAncestor = T,
|
|
748
|
-
> =
|
|
749
|
-
|
|
750
|
-
|
|
751
|
-
|
|
752
|
-
|
|
753
|
-
|
|
754
|
-
|
|
755
|
-
|
|
756
|
-
|
|
757
|
-
|
|
758
|
-
|
|
759
|
-
Controls["AllowExactly"],
|
|
760
|
-
true,
|
|
761
|
-
"no match"
|
|
762
|
-
> extends true
|
|
763
|
-
? /* exact allowed type => */ T
|
|
764
|
-
: T extends object
|
|
765
|
-
? FilterPreservingFunction<
|
|
748
|
+
> =
|
|
749
|
+
/* test for recursion */
|
|
750
|
+
IfExactTypeInTuple<T, TAncestorTypes, true, "no match"> extends true
|
|
751
|
+
? /* recursion => use replacement */ TRecursionMarker
|
|
752
|
+
: /* force union separation hereafter */ T extends infer _
|
|
753
|
+
? /* test for recursion among union elements */
|
|
754
|
+
IfExactTypeInTuple<T, TAncestorTypes, true, "no match"> extends true
|
|
755
|
+
? TRecursionMarker
|
|
756
|
+
: /* test for general allowance */ T extends Controls["AllowExtensionOf"]
|
|
757
|
+
? /* allowed extension type => */ T
|
|
758
|
+
: /* test for exact allowance */ IfExactTypeInTuple<
|
|
766
759
|
T,
|
|
767
|
-
|
|
768
|
-
|
|
769
|
-
|
|
770
|
-
|
|
771
|
-
|
|
772
|
-
|
|
773
|
-
|
|
774
|
-
|
|
775
|
-
|
|
776
|
-
|
|
777
|
-
|
|
760
|
+
Controls["AllowExactly"],
|
|
761
|
+
true,
|
|
762
|
+
"no match"
|
|
763
|
+
> extends true
|
|
764
|
+
? /* exact allowed type => */ T
|
|
765
|
+
: T extends object
|
|
766
|
+
? FilterPreservingFunction<
|
|
767
|
+
T,
|
|
768
|
+
{
|
|
769
|
+
[K in keyof T]: ReplaceRecursionWithMarkerAndPreserveAllowances<
|
|
770
|
+
T[K],
|
|
771
|
+
TRecursionMarker,
|
|
772
|
+
Controls,
|
|
773
|
+
[TNextAncestor, ...TAncestorTypes]
|
|
774
|
+
>;
|
|
775
|
+
}
|
|
776
|
+
>
|
|
777
|
+
: /* non-object => T as is */ T
|
|
778
|
+
: never;
|
|
778
779
|
|
|
779
780
|
/**
|
|
780
781
|
* Replaces any instances of "allowed" types and recursion within with `never`.
|
|
@@ -792,41 +793,42 @@ export namespace InternalUtilityTypes {
|
|
|
792
793
|
Controls extends FilterControls,
|
|
793
794
|
TAncestorTypes extends unknown[] = [],
|
|
794
795
|
TNextAncestor = T,
|
|
795
|
-
> =
|
|
796
|
-
|
|
797
|
-
|
|
798
|
-
|
|
799
|
-
|
|
800
|
-
|
|
801
|
-
|
|
802
|
-
|
|
803
|
-
|
|
804
|
-
|
|
805
|
-
|
|
806
|
-
Controls["AllowExactly"],
|
|
807
|
-
true,
|
|
808
|
-
"no match"
|
|
809
|
-
> extends true
|
|
810
|
-
? /* exact allowed type => */ never
|
|
811
|
-
: /* test for recursion among union elements */ IfExactTypeInTuple<
|
|
796
|
+
> =
|
|
797
|
+
/* test for exact recursion first */ IfExactTypeInTuple<
|
|
798
|
+
T,
|
|
799
|
+
TAncestorTypes,
|
|
800
|
+
true,
|
|
801
|
+
"no match"
|
|
802
|
+
> extends true
|
|
803
|
+
? /* recursion => */ never
|
|
804
|
+
: /* test for general allowance (also forces union separation) */ T extends Controls["AllowExtensionOf"]
|
|
805
|
+
? /* allowed extension type => */ never
|
|
806
|
+
: /* test for exact allowance */ IfExactTypeInTuple<
|
|
812
807
|
T,
|
|
813
|
-
|
|
808
|
+
Controls["AllowExactly"],
|
|
814
809
|
true,
|
|
815
810
|
"no match"
|
|
816
811
|
> extends true
|
|
817
|
-
? /*
|
|
818
|
-
:
|
|
819
|
-
? FilterPreservingFunction<
|
|
812
|
+
? /* exact allowed type => */ never
|
|
813
|
+
: /* test for recursion among union elements */ IfExactTypeInTuple<
|
|
820
814
|
T,
|
|
821
|
-
|
|
822
|
-
|
|
823
|
-
|
|
824
|
-
|
|
825
|
-
|
|
826
|
-
|
|
827
|
-
|
|
828
|
-
|
|
829
|
-
|
|
815
|
+
TAncestorTypes,
|
|
816
|
+
true,
|
|
817
|
+
"no match"
|
|
818
|
+
> extends true
|
|
819
|
+
? /* recursion => */ never
|
|
820
|
+
: T extends object
|
|
821
|
+
? FilterPreservingFunction<
|
|
822
|
+
T,
|
|
823
|
+
{
|
|
824
|
+
[K in keyof T]: ReplaceAllowancesAndRecursionWithNever<
|
|
825
|
+
T[K],
|
|
826
|
+
Controls,
|
|
827
|
+
[TNextAncestor, ...TAncestorTypes]
|
|
828
|
+
>;
|
|
829
|
+
}
|
|
830
|
+
>
|
|
831
|
+
: /* non-object => T as is */ T;
|
|
830
832
|
|
|
831
833
|
/**
|
|
832
834
|
* Test for non-public properties (which can only exist on class instance types).
|
|
@@ -849,9 +851,8 @@ export namespace InternalUtilityTypes {
|
|
|
849
851
|
Controls extends FilterControls,
|
|
850
852
|
HasNonPublic = never,
|
|
851
853
|
OnlyPublics = unknown,
|
|
852
|
-
> =
|
|
853
|
-
? OnlyPublics
|
|
854
|
-
: HasNonPublic;
|
|
854
|
+
> =
|
|
855
|
+
ReplaceAllowancesAndRecursionWithNever<T, Controls> extends T ? OnlyPublics : HasNonPublic;
|
|
855
856
|
|
|
856
857
|
/**
|
|
857
858
|
* Union of all types in a tuple.
|
|
@@ -878,74 +879,75 @@ export namespace InternalUtilityTypes {
|
|
|
878
879
|
},
|
|
879
880
|
TAncestorTypes extends unknown[] = [],
|
|
880
881
|
TNextAncestor = T,
|
|
881
|
-
> =
|
|
882
|
-
|
|
883
|
-
|
|
884
|
-
|
|
885
|
-
|
|
886
|
-
|
|
887
|
-
|
|
888
|
-
|
|
889
|
-
|
|
890
|
-
|
|
891
|
-
|
|
892
|
-
|
|
893
|
-
|
|
894
|
-
|
|
895
|
-
|
|
896
|
-
|
|
897
|
-
|
|
898
|
-
|
|
899
|
-
|
|
900
|
-
|
|
901
|
-
|
|
902
|
-
|
|
903
|
-
|
|
904
|
-
|
|
905
|
-
|
|
906
|
-
Controls
|
|
907
|
-
|
|
908
|
-
? /* 'any'
|
|
909
|
-
|
|
910
|
-
|
|
911
|
-
|
|
912
|
-
|
|
913
|
-
|
|
914
|
-
|
|
915
|
-
|
|
916
|
-
|
|
917
|
-
|
|
918
|
-
|
|
919
|
-
|
|
920
|
-
|
|
921
|
-
|
|
922
|
-
|
|
923
|
-
|
|
924
|
-
|
|
925
|
-
|
|
926
|
-
|
|
927
|
-
|
|
928
|
-
|
|
929
|
-
? /*
|
|
930
|
-
|
|
931
|
-
|
|
932
|
-
|
|
933
|
-
|
|
934
|
-
|
|
935
|
-
|
|
936
|
-
|
|
937
|
-
|
|
938
|
-
|
|
939
|
-
|
|
940
|
-
|
|
941
|
-
|
|
942
|
-
|
|
943
|
-
|
|
944
|
-
|
|
945
|
-
|
|
946
|
-
|
|
947
|
-
|
|
948
|
-
|
|
882
|
+
> =
|
|
883
|
+
/* Build Controls from Options filling in defaults for any missing properties */
|
|
884
|
+
{
|
|
885
|
+
AllowExactly: Options extends { AllowExactly: unknown[] } ? Options["AllowExactly"] : [];
|
|
886
|
+
AllowExtensionOf: Options extends { AllowExtensionOf: unknown }
|
|
887
|
+
? Options["AllowExtensionOf"]
|
|
888
|
+
: never;
|
|
889
|
+
// The Substitute type could be extracted to helper type, but is kept explicit here
|
|
890
|
+
// to make JsonTypeWith and OpaqueJsonSerializable show explicitly in results for
|
|
891
|
+
// users, rather than either the helper type name or a partially unrolled version.
|
|
892
|
+
DegenerateSubstitute:
|
|
893
|
+
| JsonTypeWith<
|
|
894
|
+
| (Options extends { AllowExactly: unknown[] }
|
|
895
|
+
? TupleToUnion<Options["AllowExactly"]>
|
|
896
|
+
: never)
|
|
897
|
+
| (Options extends { AllowExtensionOf: unknown }
|
|
898
|
+
? Options["AllowExtensionOf"]
|
|
899
|
+
: never)
|
|
900
|
+
>
|
|
901
|
+
| OpaqueJsonSerializable<
|
|
902
|
+
unknown,
|
|
903
|
+
Options extends { AllowExactly: unknown[] } ? Options["AllowExactly"] : [],
|
|
904
|
+
Options extends { AllowExtensionOf: unknown } ? Options["AllowExtensionOf"] : never
|
|
905
|
+
>;
|
|
906
|
+
} extends infer Controls
|
|
907
|
+
? /* Controls should always satisfy FilterControlsWithSubstitution, but Typescript wants a check */
|
|
908
|
+
Controls extends FilterControlsWithSubstitution
|
|
909
|
+
? /* test for 'any' */ boolean extends (T extends never ? true : false)
|
|
910
|
+
? /* 'any' => */ Controls["DegenerateSubstitute"]
|
|
911
|
+
: Options extends { IgnoreInaccessibleMembers: "ignore-inaccessible-members" }
|
|
912
|
+
? JsonSerializableFilter<T, Controls, TAncestorTypes, TNextAncestor>
|
|
913
|
+
: /* test for non-public properties (class instance type) */
|
|
914
|
+
IfNonPublicProperties<
|
|
915
|
+
T,
|
|
916
|
+
{
|
|
917
|
+
AllowExactly: Controls["AllowExactly"];
|
|
918
|
+
AllowExtensionOf:
|
|
919
|
+
| Controls["AllowExtensionOf"]
|
|
920
|
+
// Add in primitives that may be branded to ignore intersection classes
|
|
921
|
+
| boolean
|
|
922
|
+
| number
|
|
923
|
+
| string
|
|
924
|
+
// Add in OpaqueJson* types
|
|
925
|
+
| AnyOpaqueJsonType;
|
|
926
|
+
},
|
|
927
|
+
"found non-publics",
|
|
928
|
+
"only publics"
|
|
929
|
+
> extends "found non-publics"
|
|
930
|
+
? /* hidden props => test if it is array properties that are the problem */ T extends readonly (infer _)[]
|
|
931
|
+
? /* array => */ {
|
|
932
|
+
/* use homomorphic mapped type to preserve tuple type */
|
|
933
|
+
[K in keyof T]: JsonSerializableImpl<
|
|
934
|
+
T[K],
|
|
935
|
+
Controls,
|
|
936
|
+
[TNextAncestor, ...TAncestorTypes]
|
|
937
|
+
>;
|
|
938
|
+
}
|
|
939
|
+
: /* test for potentially branded primitive (intersection with a supported primitive) */
|
|
940
|
+
T extends boolean | number | string
|
|
941
|
+
? /* assume intersection is branding and allow as-is => */ T
|
|
942
|
+
: /* not array => error */ SerializationErrorPerNonPublicProperties
|
|
943
|
+
: /* no hidden properties => apply filtering => */ JsonSerializableFilter<
|
|
944
|
+
T,
|
|
945
|
+
Controls,
|
|
946
|
+
TAncestorTypes,
|
|
947
|
+
TNextAncestor
|
|
948
|
+
>
|
|
949
|
+
: never /* FilterControlsWithSubstitution assert else; should never be reached */
|
|
950
|
+
: never /* unreachable else for infer */;
|
|
949
951
|
|
|
950
952
|
/**
|
|
951
953
|
* Handle OpaqueJson* types for {@link JsonSerializable}.
|
|
@@ -968,24 +970,37 @@ export namespace InternalUtilityTypes {
|
|
|
968
970
|
export type JsonSerializableOpaqueAllowances<
|
|
969
971
|
T extends AnyOpaqueJsonType,
|
|
970
972
|
Controls extends FilterControlsWithSubstitution,
|
|
971
|
-
> =
|
|
972
|
-
|
|
973
|
-
|
|
974
|
-
|
|
975
|
-
|
|
976
|
-
|
|
977
|
-
|
|
978
|
-
|
|
979
|
-
|
|
980
|
-
|
|
981
|
-
|
|
982
|
-
|
|
973
|
+
> =
|
|
974
|
+
/* eslint-disable @typescript-eslint/no-explicit-any -- must use `any` for invariant constraint override */
|
|
975
|
+
/* infer underlying data type */ T extends
|
|
976
|
+
| OpaqueJsonSerializable<infer TData, any, unknown>
|
|
977
|
+
| OpaqueJsonDeserialized<infer TData, any, unknown>
|
|
978
|
+
? T extends OpaqueJsonSerializable<TData, any, unknown> &
|
|
979
|
+
OpaqueJsonDeserialized<TData, any, unknown>
|
|
980
|
+
? OpaqueJsonSerializable<
|
|
981
|
+
TData,
|
|
982
|
+
Controls["AllowExactly"],
|
|
983
|
+
Controls["AllowExtensionOf"]
|
|
984
|
+
> &
|
|
985
|
+
OpaqueJsonDeserialized<
|
|
983
986
|
TData,
|
|
984
987
|
Controls["AllowExactly"],
|
|
985
988
|
Controls["AllowExtensionOf"]
|
|
986
989
|
>
|
|
987
|
-
|
|
988
|
-
|
|
990
|
+
: T extends OpaqueJsonSerializable<TData, any, unknown>
|
|
991
|
+
? OpaqueJsonSerializable<
|
|
992
|
+
TData,
|
|
993
|
+
Controls["AllowExactly"],
|
|
994
|
+
Controls["AllowExtensionOf"]
|
|
995
|
+
>
|
|
996
|
+
: T extends OpaqueJsonDeserialized<TData, any, unknown>
|
|
997
|
+
? OpaqueJsonDeserialized<
|
|
998
|
+
TData,
|
|
999
|
+
Controls["AllowExactly"],
|
|
1000
|
+
Controls["AllowExtensionOf"]
|
|
1001
|
+
>
|
|
1002
|
+
: "internal error: failed to determine OpaqueJson* type"
|
|
1003
|
+
: never;
|
|
989
1004
|
/* eslint-enable @typescript-eslint/no-explicit-any */
|
|
990
1005
|
|
|
991
1006
|
/**
|
|
@@ -1153,79 +1168,90 @@ export namespace InternalUtilityTypes {
|
|
|
1153
1168
|
T,
|
|
1154
1169
|
Options extends Partial<FilterControls>,
|
|
1155
1170
|
TypeUnderRecursion extends boolean = false,
|
|
1156
|
-
> =
|
|
1157
|
-
|
|
1158
|
-
|
|
1159
|
-
|
|
1160
|
-
|
|
1161
|
-
|
|
1162
|
-
|
|
1163
|
-
|
|
1164
|
-
|
|
1165
|
-
|
|
1166
|
-
|
|
1167
|
-
|
|
1168
|
-
|
|
1169
|
-
|
|
1170
|
-
|
|
1171
|
-
|
|
1172
|
-
|
|
1173
|
-
|
|
1174
|
-
|
|
1175
|
-
|
|
1176
|
-
|
|
1177
|
-
|
|
1178
|
-
|
|
1179
|
-
|
|
1180
|
-
Controls
|
|
1181
|
-
|
|
1182
|
-
? /* 'any'
|
|
1183
|
-
|
|
1184
|
-
|
|
1185
|
-
RecursionMarker,
|
|
1186
|
-
{
|
|
1187
|
-
AllowExactly: Controls["AllowExactly"];
|
|
1188
|
-
AllowExtensionOf:
|
|
1189
|
-
| Controls["AllowExtensionOf"]
|
|
1190
|
-
// Also preserve OpaqueJson* types
|
|
1191
|
-
| AnyOpaqueJsonType;
|
|
1192
|
-
}
|
|
1193
|
-
> extends infer TNoRecursionAndOnlyPublics
|
|
1194
|
-
? /* test for no change from filtered type */ IsSameType<
|
|
1195
|
-
TNoRecursionAndOnlyPublics,
|
|
1196
|
-
JsonDeserializedFilter<
|
|
1197
|
-
TNoRecursionAndOnlyPublics,
|
|
1198
|
-
{
|
|
1199
|
-
AllowExactly: Controls["AllowExactly"];
|
|
1200
|
-
AllowExtensionOf: Controls["AllowExtensionOf"];
|
|
1201
|
-
DegenerateSubstitute: Controls["DegenerateSubstitute"];
|
|
1202
|
-
DegenerateNonNullObjectSubstitute: Controls["DegenerateNonNullObjectSubstitute"];
|
|
1203
|
-
RecursionMarkerAllowed: RecursionMarker;
|
|
1204
|
-
}
|
|
1205
|
-
>
|
|
1206
|
-
> extends true
|
|
1207
|
-
? /* same (no filtering needed) => test for non-public
|
|
1208
|
-
properties (class instance type) */
|
|
1209
|
-
IfNonPublicProperties<
|
|
1171
|
+
> =
|
|
1172
|
+
/* Build Controls from Options filling in defaults for any missing properties */
|
|
1173
|
+
{
|
|
1174
|
+
AllowExactly: Options extends { AllowExactly: unknown[] } ? Options["AllowExactly"] : [];
|
|
1175
|
+
AllowExtensionOf: Options extends { AllowExtensionOf: unknown }
|
|
1176
|
+
? Options["AllowExtensionOf"]
|
|
1177
|
+
: never;
|
|
1178
|
+
// The Substitute types could be extracted to helper type, but are kept explicit here
|
|
1179
|
+
// to make JsonTypeWith/NonNullJsonObjectWith show explicitly in results for users, rather
|
|
1180
|
+
// than either the helper type name or a partially unrolled version.
|
|
1181
|
+
DegenerateSubstitute: JsonTypeWith<
|
|
1182
|
+
| (Options extends { AllowExactly: unknown[] }
|
|
1183
|
+
? TupleToUnion<Options["AllowExactly"]>
|
|
1184
|
+
: never)
|
|
1185
|
+
| (Options extends { AllowExtensionOf: unknown } ? Options["AllowExtensionOf"] : never)
|
|
1186
|
+
>;
|
|
1187
|
+
DegenerateNonNullObjectSubstitute: NonNullJsonObjectWith<
|
|
1188
|
+
| (Options extends { AllowExactly: unknown[] }
|
|
1189
|
+
? TupleToUnion<Options["AllowExactly"]>
|
|
1190
|
+
: never)
|
|
1191
|
+
| (Options extends { AllowExtensionOf: unknown } ? Options["AllowExtensionOf"] : never)
|
|
1192
|
+
>;
|
|
1193
|
+
RecursionMarkerAllowed: never;
|
|
1194
|
+
} extends infer Controls
|
|
1195
|
+
? /* Controls should always satisfy DeserializedFilterControls, but Typescript wants a check */
|
|
1196
|
+
Controls extends DeserializedFilterControls
|
|
1197
|
+
? /* test for 'any' */ boolean extends (T extends never ? true : false)
|
|
1198
|
+
? /* 'any' => */ Controls["DegenerateSubstitute"]
|
|
1199
|
+
: /* infer non-recursive version of T */ ReplaceRecursionWithMarkerAndPreserveAllowances<
|
|
1210
1200
|
T,
|
|
1211
|
-
|
|
1212
|
-
// primitives as JsonDeserializedFilter will allow them as
|
|
1213
|
-
// extensions of the primitives. Should there be a need to
|
|
1214
|
-
// explicitly allow them here, see JsonSerializableImpl's use.
|
|
1201
|
+
RecursionMarker,
|
|
1215
1202
|
{
|
|
1216
1203
|
AllowExactly: Controls["AllowExactly"];
|
|
1217
1204
|
AllowExtensionOf:
|
|
1218
1205
|
| Controls["AllowExtensionOf"]
|
|
1219
|
-
//
|
|
1206
|
+
// Also preserve OpaqueJson* types
|
|
1220
1207
|
| AnyOpaqueJsonType;
|
|
1221
|
-
}
|
|
1222
|
-
|
|
1223
|
-
|
|
1224
|
-
|
|
1225
|
-
|
|
1208
|
+
}
|
|
1209
|
+
> extends infer TNoRecursionAndOnlyPublics
|
|
1210
|
+
? /* test for no change from filtered type */ IsSameType<
|
|
1211
|
+
TNoRecursionAndOnlyPublics,
|
|
1212
|
+
JsonDeserializedFilter<
|
|
1213
|
+
TNoRecursionAndOnlyPublics,
|
|
1214
|
+
{
|
|
1215
|
+
AllowExactly: Controls["AllowExactly"];
|
|
1216
|
+
AllowExtensionOf: Controls["AllowExtensionOf"];
|
|
1217
|
+
DegenerateSubstitute: Controls["DegenerateSubstitute"];
|
|
1218
|
+
DegenerateNonNullObjectSubstitute: Controls["DegenerateNonNullObjectSubstitute"];
|
|
1219
|
+
RecursionMarkerAllowed: RecursionMarker;
|
|
1220
|
+
}
|
|
1221
|
+
>
|
|
1222
|
+
> extends true
|
|
1223
|
+
? /* same (no filtering needed) => test for non-public
|
|
1224
|
+
properties (class instance type) */
|
|
1225
|
+
IfNonPublicProperties<
|
|
1226
|
+
T,
|
|
1227
|
+
// Note: no extra allowance is made here for possible branded
|
|
1228
|
+
// primitives as JsonDeserializedFilter will allow them as
|
|
1229
|
+
// extensions of the primitives. Should there be a need to
|
|
1230
|
+
// explicitly allow them here, see JsonSerializableImpl's use.
|
|
1231
|
+
{
|
|
1232
|
+
AllowExactly: Controls["AllowExactly"];
|
|
1233
|
+
AllowExtensionOf:
|
|
1234
|
+
| Controls["AllowExtensionOf"]
|
|
1235
|
+
// Add in OpaqueJson* types
|
|
1236
|
+
| AnyOpaqueJsonType;
|
|
1237
|
+
},
|
|
1238
|
+
"found non-publics",
|
|
1239
|
+
"only publics"
|
|
1240
|
+
> extends "found non-publics"
|
|
1241
|
+
? /* hidden props => apply filtering to avoid retaining
|
|
1226
1242
|
exact class except for any classes in allowances =>
|
|
1227
1243
|
test for known recursion */
|
|
1228
|
-
|
|
1244
|
+
TypeUnderRecursion extends false
|
|
1245
|
+
? /* no known recursion => */ JsonDeserializedFilter<T, Controls>
|
|
1246
|
+
: /* known recursion => use OpaqueJsonDeserialized for later processing */
|
|
1247
|
+
OpaqueJsonDeserialized<
|
|
1248
|
+
T,
|
|
1249
|
+
Controls["AllowExactly"],
|
|
1250
|
+
Controls["AllowExtensionOf"]
|
|
1251
|
+
>
|
|
1252
|
+
: /* no hidden properties => deserialized T is just T */
|
|
1253
|
+
T
|
|
1254
|
+
: /* filtering is needed => test for known recursion */ TypeUnderRecursion extends false
|
|
1229
1255
|
? /* no known recursion => */ JsonDeserializedFilter<T, Controls>
|
|
1230
1256
|
: /* known recursion => use OpaqueJsonDeserialized for later processing */
|
|
1231
1257
|
OpaqueJsonDeserialized<
|
|
@@ -1233,19 +1259,9 @@ export namespace InternalUtilityTypes {
|
|
|
1233
1259
|
Controls["AllowExactly"],
|
|
1234
1260
|
Controls["AllowExtensionOf"]
|
|
1235
1261
|
>
|
|
1236
|
-
|
|
1237
|
-
|
|
1238
|
-
|
|
1239
|
-
? /* no known recursion => */ JsonDeserializedFilter<T, Controls>
|
|
1240
|
-
: /* known recursion => use OpaqueJsonDeserialized for later processing */
|
|
1241
|
-
OpaqueJsonDeserialized<
|
|
1242
|
-
T,
|
|
1243
|
-
Controls["AllowExactly"],
|
|
1244
|
-
Controls["AllowExtensionOf"]
|
|
1245
|
-
>
|
|
1246
|
-
: /* unreachable else for infer */ never
|
|
1247
|
-
: never /* DeserializedFilterControls assert else; should never be reached */
|
|
1248
|
-
: never /* unreachable else for infer */;
|
|
1262
|
+
: /* unreachable else for infer */ never
|
|
1263
|
+
: never /* DeserializedFilterControls assert else; should never be reached */
|
|
1264
|
+
: never /* unreachable else for infer */;
|
|
1249
1265
|
|
|
1250
1266
|
/**
|
|
1251
1267
|
* Recurses `T` applying {@link InternalCoreInterfacesUtilityTypes.JsonDeserializedFilter} up until
|
|
@@ -1265,27 +1281,28 @@ export namespace InternalUtilityTypes {
|
|
|
1265
1281
|
T,
|
|
1266
1282
|
Controls extends DeserializedFilterControls,
|
|
1267
1283
|
TAncestorTypes extends object[],
|
|
1268
|
-
> =
|
|
1269
|
-
|
|
1284
|
+
> =
|
|
1285
|
+
IfExactTypeInTuple<T, TAncestorTypes, true, "no match"> extends true
|
|
1286
|
+
? /* recursion found => reprocess that recursive type directly to avoid
|
|
1270
1287
|
any collateral damage from ancestor type that required modification.
|
|
1271
1288
|
Further recursion will not happen during processing. Either:
|
|
1272
1289
|
- the type requires modification and the `TypeUnderRecursion=true`
|
|
1273
1290
|
arg will result in `OpaqueJsonDeserialized<T>` wrapper OR
|
|
1274
1291
|
- no change is needed from this point and `T` will result. */
|
|
1275
|
-
|
|
1276
|
-
|
|
1277
|
-
|
|
1278
|
-
|
|
1279
|
-
|
|
1292
|
+
JsonDeserializedImpl<T, Controls, true>
|
|
1293
|
+
: T extends object
|
|
1294
|
+
? IfExactTypeInTuple<T, TAncestorTypes, true, "no match"> extends true
|
|
1295
|
+
? JsonDeserializedImpl<T, Controls, true>
|
|
1296
|
+
: /* no recursion yet detected => */ JsonDeserializedFilter<
|
|
1297
|
+
T,
|
|
1298
|
+
Controls,
|
|
1299
|
+
[...TAncestorTypes, T]
|
|
1300
|
+
>
|
|
1301
|
+
: /* not an object (no recursion) => */ JsonDeserializedFilter<
|
|
1280
1302
|
T,
|
|
1281
1303
|
Controls,
|
|
1282
|
-
|
|
1283
|
-
|
|
1284
|
-
: /* not an object (no recursion) => */ JsonDeserializedFilter<
|
|
1285
|
-
T,
|
|
1286
|
-
Controls,
|
|
1287
|
-
TAncestorTypes
|
|
1288
|
-
>;
|
|
1304
|
+
TAncestorTypes
|
|
1305
|
+
>;
|
|
1289
1306
|
|
|
1290
1307
|
/**
|
|
1291
1308
|
* Handle OpaqueJson* types for {@link JsonDeserialized}.
|
|
@@ -1308,12 +1325,13 @@ export namespace InternalUtilityTypes {
|
|
|
1308
1325
|
export type JsonDeserializedOpaqueConversion<
|
|
1309
1326
|
T extends AnyOpaqueJsonType,
|
|
1310
1327
|
Controls extends FilterControls,
|
|
1311
|
-
> =
|
|
1312
|
-
|
|
1313
|
-
|
|
1314
|
-
|
|
1315
|
-
|
|
1316
|
-
|
|
1328
|
+
> =
|
|
1329
|
+
/* eslint-disable @typescript-eslint/no-explicit-any -- must use `any` for invariant constraint override */
|
|
1330
|
+
T extends
|
|
1331
|
+
| OpaqueJsonSerializable<infer TData, any, unknown>
|
|
1332
|
+
| OpaqueJsonDeserialized<infer TData, any, unknown>
|
|
1333
|
+
? OpaqueJsonDeserialized<TData, Controls["AllowExactly"], Controls["AllowExtensionOf"]>
|
|
1334
|
+
: "internal error: failed to determine OpaqueJson* type";
|
|
1317
1335
|
/* eslint-enable @typescript-eslint/no-explicit-any */
|
|
1318
1336
|
|
|
1319
1337
|
/**
|
|
@@ -1418,14 +1436,15 @@ export namespace InternalUtilityTypes {
|
|
|
1418
1436
|
DeepenedGenerics extends ReadonlySupportedGenerics,
|
|
1419
1437
|
NoDepthOrRecurseLimit extends "Shallow" | DeepReadonlyRecursionLimit,
|
|
1420
1438
|
Else,
|
|
1421
|
-
> =
|
|
1422
|
-
|
|
1423
|
-
?
|
|
1424
|
-
|
|
1425
|
-
|
|
1426
|
-
|
|
1427
|
-
|
|
1428
|
-
|
|
1439
|
+
> =
|
|
1440
|
+
T extends ReadonlyMap<infer K, infer V>
|
|
1441
|
+
? Map<K, V> extends DeepenedGenerics
|
|
1442
|
+
? ReadonlyMap<
|
|
1443
|
+
ReadonlyImpl<K, DeepenedGenerics, NoDepthOrRecurseLimit>,
|
|
1444
|
+
ReadonlyImpl<V, DeepenedGenerics, NoDepthOrRecurseLimit>
|
|
1445
|
+
>
|
|
1446
|
+
: ReadonlyMap<K, V>
|
|
1447
|
+
: Else;
|
|
1429
1448
|
|
|
1430
1449
|
/**
|
|
1431
1450
|
* If `T` is a `Set<TSet>` or `ReadonlySet<TSet>`, returns `ReadonlySet` and,
|
|
@@ -1439,11 +1458,12 @@ export namespace InternalUtilityTypes {
|
|
|
1439
1458
|
DeepenedGenerics extends ReadonlySupportedGenerics,
|
|
1440
1459
|
NoDepthOrRecurseLimit extends "Shallow" | DeepReadonlyRecursionLimit,
|
|
1441
1460
|
Else,
|
|
1442
|
-
> =
|
|
1443
|
-
|
|
1444
|
-
?
|
|
1445
|
-
|
|
1446
|
-
|
|
1461
|
+
> =
|
|
1462
|
+
T extends ReadonlySet<infer V>
|
|
1463
|
+
? Set<V> extends DeepenedGenerics
|
|
1464
|
+
? ReadonlySet<ReadonlyImpl<V, DeepenedGenerics, NoDepthOrRecurseLimit>>
|
|
1465
|
+
: ReadonlySet<V>
|
|
1466
|
+
: Else;
|
|
1447
1467
|
|
|
1448
1468
|
/**
|
|
1449
1469
|
* If `T` is a `IFluidHandle<THandle>` and if `T` extends `DeepenedGenerics`,
|
|
@@ -1457,11 +1477,12 @@ export namespace InternalUtilityTypes {
|
|
|
1457
1477
|
DeepenedGenerics extends ReadonlySupportedGenerics,
|
|
1458
1478
|
NoDepthOrRecurseLimit extends "Shallow" | DeepReadonlyRecursionLimit,
|
|
1459
1479
|
Else,
|
|
1460
|
-
> =
|
|
1461
|
-
|
|
1462
|
-
?
|
|
1463
|
-
|
|
1464
|
-
|
|
1480
|
+
> =
|
|
1481
|
+
T extends Readonly<IFluidHandle<infer V>>
|
|
1482
|
+
? IFluidHandle<V> extends DeepenedGenerics
|
|
1483
|
+
? Readonly<IFluidHandle<ReadonlyImpl<V, DeepenedGenerics, NoDepthOrRecurseLimit>>>
|
|
1484
|
+
: Readonly<T>
|
|
1485
|
+
: Else;
|
|
1465
1486
|
|
|
1466
1487
|
/**
|
|
1467
1488
|
* If `T` is a `Promise<TPromise>` and if `T` extends `DeepenedGenerics`,
|
|
@@ -1475,11 +1496,12 @@ export namespace InternalUtilityTypes {
|
|
|
1475
1496
|
DeepenedGenerics extends ReadonlySupportedGenerics,
|
|
1476
1497
|
NoDepthOrRecurseLimit extends "Shallow" | DeepReadonlyRecursionLimit,
|
|
1477
1498
|
Else,
|
|
1478
|
-
> =
|
|
1479
|
-
|
|
1480
|
-
? Promise<
|
|
1481
|
-
|
|
1482
|
-
|
|
1499
|
+
> =
|
|
1500
|
+
T extends Promise<infer V>
|
|
1501
|
+
? Promise<V> extends DeepenedGenerics
|
|
1502
|
+
? Promise<ReadonlyImpl<V, DeepenedGenerics, NoDepthOrRecurseLimit>>
|
|
1503
|
+
: T
|
|
1504
|
+
: Else;
|
|
1483
1505
|
|
|
1484
1506
|
/**
|
|
1485
1507
|
* If `T` is a `WeakMap<K,V>`, returns immutable `WeakMap` and,
|
|
@@ -1493,17 +1515,18 @@ export namespace InternalUtilityTypes {
|
|
|
1493
1515
|
DeepenedGenerics extends ReadonlySupportedGenerics,
|
|
1494
1516
|
NoDepthOrRecurseLimit extends "Shallow" | DeepReadonlyRecursionLimit,
|
|
1495
1517
|
Else,
|
|
1496
|
-
> =
|
|
1497
|
-
|
|
1498
|
-
?
|
|
1499
|
-
|
|
1500
|
-
|
|
1501
|
-
|
|
1502
|
-
|
|
1503
|
-
|
|
1504
|
-
|
|
1505
|
-
|
|
1506
|
-
|
|
1518
|
+
> =
|
|
1519
|
+
T extends Omit<WeakMap<infer K, infer V>, "delete" | "set">
|
|
1520
|
+
? WeakMap<K, V> extends DeepenedGenerics
|
|
1521
|
+
? Omit<
|
|
1522
|
+
WeakMap<
|
|
1523
|
+
ReadonlyImpl<K, DeepenedGenerics, NoDepthOrRecurseLimit>,
|
|
1524
|
+
ReadonlyImpl<V, DeepenedGenerics, NoDepthOrRecurseLimit>
|
|
1525
|
+
>,
|
|
1526
|
+
"delete" | "set"
|
|
1527
|
+
>
|
|
1528
|
+
: Omit<WeakMap<K, V>, "delete" | "set">
|
|
1529
|
+
: Else;
|
|
1507
1530
|
|
|
1508
1531
|
/**
|
|
1509
1532
|
* If `T` is a `WeakSet<TSet>`, returns immutable `WeakSet` and,
|
|
@@ -1517,14 +1540,15 @@ export namespace InternalUtilityTypes {
|
|
|
1517
1540
|
DeepenedGenerics extends ReadonlySupportedGenerics,
|
|
1518
1541
|
NoDepthOrRecurseLimit extends "Shallow" | DeepReadonlyRecursionLimit,
|
|
1519
1542
|
Else,
|
|
1520
|
-
> =
|
|
1521
|
-
|
|
1522
|
-
?
|
|
1523
|
-
|
|
1524
|
-
|
|
1525
|
-
|
|
1526
|
-
|
|
1527
|
-
|
|
1543
|
+
> =
|
|
1544
|
+
T extends Omit<WeakSet<infer V>, "add" | "delete">
|
|
1545
|
+
? WeakSet<V> extends DeepenedGenerics
|
|
1546
|
+
? Omit<
|
|
1547
|
+
WeakSet<ReadonlyImpl<V, DeepenedGenerics, NoDepthOrRecurseLimit>>,
|
|
1548
|
+
"add" | "delete"
|
|
1549
|
+
>
|
|
1550
|
+
: Omit<WeakSet<V>, "add" | "delete">
|
|
1551
|
+
: Else;
|
|
1528
1552
|
|
|
1529
1553
|
/**
|
|
1530
1554
|
* If `T` is a {@link ReadonlySupportedGenerics}, `T` is returned as
|
|
@@ -1577,19 +1601,17 @@ export namespace InternalUtilityTypes {
|
|
|
1577
1601
|
*
|
|
1578
1602
|
* @system
|
|
1579
1603
|
*/
|
|
1580
|
-
export type PreserveErasedTypeOrBrandedPrimitive<
|
|
1581
|
-
T extends
|
|
1582
|
-
|
|
1583
|
-
|
|
1584
|
-
|
|
1585
|
-
|
|
1586
|
-
|
|
1587
|
-
|
|
1588
|
-
|
|
1589
|
-
|
|
1590
|
-
|
|
1591
|
-
: /* Should never be reached */ T
|
|
1592
|
-
: Else;
|
|
1604
|
+
export type PreserveErasedTypeOrBrandedPrimitive<T extends object, Else> =
|
|
1605
|
+
/* Test for erased type */ T extends ErasedType<infer _>
|
|
1606
|
+
? /* erased type => keep as-is */ T
|
|
1607
|
+
: /* Test for branded primitive */ T extends infer Brand &
|
|
1608
|
+
(boolean | number | string | symbol | bigint)
|
|
1609
|
+
? // Should just return T here, but TypeScript appears to produce `never` when doing so.
|
|
1610
|
+
// Workaround by inferring the Primitive type and returning intersection with B.
|
|
1611
|
+
T extends Brand & infer Primitive
|
|
1612
|
+
? /* [potentially] branded type => "as-is" */ Primitive & Brand
|
|
1613
|
+
: /* Should never be reached */ T
|
|
1614
|
+
: Else;
|
|
1593
1615
|
|
|
1594
1616
|
/**
|
|
1595
1617
|
* De-multiplexing implementation of {@link DeepReadonly} and {@link ShallowReadonly}
|
|
@@ -1724,40 +1746,41 @@ export namespace InternalUtilityTypes {
|
|
|
1724
1746
|
T,
|
|
1725
1747
|
DeepenedGenerics extends ReadonlySupportedGenerics,
|
|
1726
1748
|
NoDepthOrRecurseLimit extends RecursionLimit,
|
|
1727
|
-
> =
|
|
1728
|
-
T
|
|
1729
|
-
|
|
1730
|
-
|
|
1731
|
-
|
|
1732
|
-
|
|
1733
|
-
|
|
1734
|
-
|
|
1735
|
-
|
|
1736
|
-
|
|
1737
|
-
|
|
1738
|
-
|
|
1739
|
-
|
|
1740
|
-
|
|
1741
|
-
|
|
1742
|
-
|
|
1743
|
-
|
|
1744
|
-
|
|
1745
|
-
|
|
1746
|
-
|
|
1747
|
-
|
|
1748
|
-
|
|
1749
|
+
> =
|
|
1750
|
+
/* infer non-recursive version of T */ ReplaceRecursionWithMarkerAndPreserveAllowances<
|
|
1751
|
+
T,
|
|
1752
|
+
RecursionMarker,
|
|
1753
|
+
{ AllowExactly: []; AllowExtensionOf: never }
|
|
1754
|
+
> extends infer TNoRecursionAndOnlyPublics
|
|
1755
|
+
? /* test for no change from altered type (excluding non-publics) */ IsSameType<
|
|
1756
|
+
TNoRecursionAndOnlyPublics,
|
|
1757
|
+
DeepReadonlyWorker<TNoRecursionAndOnlyPublics, DeepenedGenerics, 0>
|
|
1758
|
+
> extends true
|
|
1759
|
+
? /* same (no filtering needed) => test for non-public properties (class instance type) */
|
|
1760
|
+
IfNonPublicProperties<
|
|
1761
|
+
T,
|
|
1762
|
+
// Note: no extra allowance is made here for possible branded
|
|
1763
|
+
// primitives as DeepReadonlyWorker will allow them as
|
|
1764
|
+
// extensions of the primitives. Should there need a need to
|
|
1765
|
+
// explicit allow them here, see JsonSerializableImpl's use.
|
|
1766
|
+
{ AllowExactly: []; AllowExtensionOf: never },
|
|
1767
|
+
"found non-publics",
|
|
1768
|
+
"only publics"
|
|
1769
|
+
> extends "found non-publics"
|
|
1770
|
+
? /* hidden props => apply filtering => */
|
|
1771
|
+
DeepReadonlyWorker<
|
|
1772
|
+
T,
|
|
1773
|
+
DeepenedGenerics,
|
|
1774
|
+
Extract<NoDepthOrRecurseLimit, RecursionLimit>
|
|
1775
|
+
>
|
|
1776
|
+
: /* no hidden properties => readonly T is just T */
|
|
1777
|
+
T
|
|
1778
|
+
: /* filtering is needed => */ DeepReadonlyWorker<
|
|
1749
1779
|
T,
|
|
1750
1780
|
DeepenedGenerics,
|
|
1751
1781
|
Extract<NoDepthOrRecurseLimit, RecursionLimit>
|
|
1752
1782
|
>
|
|
1753
|
-
|
|
1754
|
-
T
|
|
1755
|
-
: /* filtering is needed => */ DeepReadonlyWorker<
|
|
1756
|
-
T,
|
|
1757
|
-
DeepenedGenerics,
|
|
1758
|
-
Extract<NoDepthOrRecurseLimit, RecursionLimit>
|
|
1759
|
-
>
|
|
1760
|
-
: /* unreachable else for infer */ never;
|
|
1783
|
+
: /* unreachable else for infer */ never;
|
|
1761
1784
|
|
|
1762
1785
|
/**
|
|
1763
1786
|
* Recurses `T` applying {@link InternalCoreInterfacesUtilityTypes.DeepReadonlyWorker} up to `RecurseLimit` times.
|