Skip to content

Commit 415ec2d

Browse files
authored
feat(client-core-interfaces): DeepReadonly and ShallowReadonly utility types (#24265)
Alternates to `Readonly` that handle `Map`, `Set`, `Promise`, `WeakMap`, and `WeakSet` by providing readonly equivalents. The generic types of those and `IFluidHandle` may also optionally be changed to readonly types. `DeepReadonly` will also apply readonly throughout the entire type not just at the outer level. Additionally, the utility types respect FF's `ErasedType` and class branded primitives. Also add `ReadonlyJsonTypeWith` and (internal) `ReadonlyNonNullJsonObjectWith` as immutable versions of `JsonTypeWith` and `NonNullJsonObjectWith` respectively. These are used to create readonly versions of the `JsonTypeWith` and `NonNullJsonObjectWith` types.
1 parent b3bfbff commit 415ec2d

11 files changed

+3435
-27
lines changed

Diff for: packages/common/core-interfaces/src/deepReadonly.ts

+76
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,76 @@
1+
/*!
2+
* Copyright (c) Microsoft Corporation and contributors. All rights reserved.
3+
* Licensed under the MIT License.
4+
*/
5+
6+
import type {
7+
DeepReadonlyRecursionLimit,
8+
InternalUtilityTypes,
9+
ReadonlySupportedGenerics,
10+
} from "./exposedInternalUtilityTypes.js";
11+
12+
/**
13+
* Default set of generic that {@link DeepReadonly} will apply deep immutability
14+
* to generic types.
15+
*
16+
* @privateRemarks
17+
* WeakRef should be added when lib is updated to ES2021 or later.
18+
*
19+
* @system
20+
*/
21+
export type DeepReadonlySupportedGenericsDefault =
22+
| Map<unknown, unknown>
23+
| Promise<unknown>
24+
| Set<unknown>
25+
| WeakMap<object, unknown>
26+
| WeakSet<object>;
27+
28+
/**
29+
* Options for {@link DeepReadonly}.
30+
*
31+
* @beta
32+
*/
33+
export interface DeepReadonlyOptions {
34+
/**
35+
* Union of Built-in and IFluidHandle whose generics will also be made deeply immutable.
36+
*
37+
* The default value is `Map` | `Promise` | `Set` | `WeakMap` | `WeakSet`.
38+
*/
39+
DeepenedGenerics?: ReadonlySupportedGenerics;
40+
41+
/**
42+
* Limit on processing recursive types.
43+
*
44+
* The default value is `"NoLimit"`.
45+
*/
46+
RecurseLimit?: DeepReadonlyRecursionLimit;
47+
}
48+
49+
/**
50+
* Transforms type to a fully and deeply immutable type, with limitations.
51+
*
52+
* @remarks
53+
* This utility type is similar to a recursive `Readonly<T>`, but also
54+
* applies immutability to common generic types like `Map` and `Set`.
55+
*
56+
* Optionally, immutability can be applied to supported generics types. See
57+
* {@link DeepReadonlySupportedGenericsDefault} for generics that have
58+
* immutability applied to generic type by default.
59+
*
60+
* @beta
61+
*/
62+
export type DeepReadonly<
63+
T,
64+
Options extends DeepReadonlyOptions = {
65+
DeepenedGenerics: DeepReadonlySupportedGenericsDefault;
66+
RecurseLimit: "NoLimit";
67+
},
68+
> = InternalUtilityTypes.DeepReadonlyImpl<
69+
T,
70+
Options extends { DeepenedGenerics: unknown }
71+
? Options["DeepenedGenerics"]
72+
: DeepReadonlySupportedGenericsDefault,
73+
Options extends { RecurseLimit: DeepReadonlyRecursionLimit }
74+
? Options["RecurseLimit"]
75+
: "NoLimit"
76+
>;

0 commit comments

Comments
 (0)