@fluidframework/core-interfaces
Advanced tools
Comparing version
# @fluidframework/core-interfaces | ||
## 2.42.0 | ||
Dependency updates only. | ||
## 2.41.0 | ||
@@ -4,0 +8,0 @@ |
@@ -9,2 +9,3 @@ /*! | ||
import type { JsonTypeWith, NonNullJsonObjectWith, ReadonlyJsonTypeWith } from "./jsonType.js"; | ||
import type { OpaqueJsonDeserialized, OpaqueJsonSerializable } from "./opaqueJson.js"; | ||
/** | ||
@@ -323,2 +324,11 @@ * Unique symbol for recursion meta-typing. | ||
/** | ||
* Convenience constraint for any Opaque Json type. | ||
* | ||
* @remarks | ||
* Use in extends check: `T extends AnyOpaqueJsonType` | ||
* | ||
* @system | ||
*/ | ||
export type AnyOpaqueJsonType = OpaqueJsonSerializable<unknown, any, unknown> | OpaqueJsonDeserialized<unknown, any, unknown>; | ||
/** | ||
* Extracts Function portion from an intersection (&) type returning | ||
@@ -440,6 +450,10 @@ * the extracted portion in the `function` property or `unknown` if | ||
AllowExtensionOf: unknown; | ||
} ? Options["AllowExtensionOf"] : never)>; | ||
} ? Options["AllowExtensionOf"] : never)> | OpaqueJsonSerializable<unknown, Options extends { | ||
AllowExactly: unknown[]; | ||
} ? Options["AllowExactly"] : [], Options extends { | ||
AllowExtensionOf: unknown; | ||
} ? Options["AllowExtensionOf"] : never>; | ||
} extends infer Controls ? Controls extends FilterControlsWithSubstitution ? boolean extends (T extends never ? true : false) ? Controls["DegenerateSubstitute"] : Options["IgnoreInaccessibleMembers"] extends "ignore-inaccessible-members" ? JsonSerializableFilter<T, Controls, TAncestorTypes, TNextAncestor> : IfNonPublicProperties<T, { | ||
AllowExactly: Controls["AllowExactly"]; | ||
AllowExtensionOf: Controls["AllowExtensionOf"] | boolean | number | string; | ||
AllowExtensionOf: Controls["AllowExtensionOf"] | boolean | number | string | AnyOpaqueJsonType; | ||
DegenerateSubstitute: Controls["DegenerateSubstitute"]; | ||
@@ -453,2 +467,21 @@ }, "found non-publics", "only publics"> extends "found non-publics" ? T extends readonly (infer _)[] ? { | ||
/** | ||
* Handle Opaque Json types for {@link JsonSerializable}. | ||
* | ||
* @remarks | ||
* {@link OpaqueJsonSerializable} and {@link OpaqueJsonDeserialized} instances | ||
* are limited to `Controls` given context supports. | ||
* `T` from the original Opaque type is preserved. In the case that this now | ||
* produces an improper type such as a `bigint` being let through that is no | ||
* longer supported, then the variance of `Controls` is expected to raise | ||
* the incompatibility error. | ||
* | ||
* @privateRemarks | ||
* Additional intersections beyond {@link OpaqueJsonSerializable}, | ||
* {@link OpaqueJsonDeserialized}, or intersected matching opaque pair are | ||
* not correctly filtered as need is not expected. | ||
* | ||
* @system | ||
*/ | ||
export type JsonSerializableOpaqueAllowances<T extends AnyOpaqueJsonType, Controls extends FilterControlsWithSubstitution> = T extends OpaqueJsonSerializable<infer TData, any, unknown> | OpaqueJsonDeserialized<infer TData, any, unknown> ? T extends OpaqueJsonSerializable<TData, any, unknown> & OpaqueJsonDeserialized<TData, any, unknown> ? OpaqueJsonSerializable<TData, Controls["AllowExactly"], Controls["AllowExtensionOf"]> & OpaqueJsonDeserialized<TData, Controls["AllowExactly"], Controls["AllowExtensionOf"]> : T extends OpaqueJsonSerializable<TData, any, unknown> ? OpaqueJsonSerializable<TData, Controls["AllowExactly"], Controls["AllowExtensionOf"]> : T extends OpaqueJsonDeserialized<TData, any, unknown> ? OpaqueJsonDeserialized<TData, Controls["AllowExactly"], Controls["AllowExtensionOf"]> : "internal error: failed to determine Opaque Json type" : never; | ||
/** | ||
* Essentially a check for a template literal that has $\{string\} or | ||
@@ -492,3 +525,3 @@ * $\{number\} in the pattern. Just `string` and/or `number` also match. | ||
]>>; | ||
} : IsExactlyObject<T> extends true ? NonNullJsonObjectWith<TupleToUnion<Controls["AllowExactly"]> | Controls["AllowExtensionOf"]> : IfEnumLike<T> extends never ? T : FlattenIntersection<{ | ||
} : IsExactlyObject<T> extends true ? NonNullJsonObjectWith<TupleToUnion<Controls["AllowExactly"]> | Controls["AllowExtensionOf"]> : IfEnumLike<T> extends never ? T : T extends AnyOpaqueJsonType ? JsonSerializableOpaqueAllowances<T, Controls> : FlattenIntersection<{ | ||
[K in keyof T as RequiredNonSymbolKeysOf<T, K>]-?: IfPossiblyUndefinedProperty<K, T[K], { | ||
@@ -568,2 +601,21 @@ IfPossiblyUndefined: { | ||
/** | ||
* Handle Opaque Json types for {@link JsonDeserialized}. | ||
* | ||
* @remarks | ||
* {@link OpaqueJsonSerializable} instances are converted to {@link OpaqueJsonDeserialized}. | ||
* The `AllowExactly` and `AllowExtensionOf` properties are set to match the given `Controls`. | ||
* The data type is kept exactly as-is to avoid processing in generic contexts that can't | ||
* produce a meaningful result. The data type should always be filtered through | ||
* {@link JsonDeserialized} when {@link OpaqueJsonDeserialized} is cracked open. So, really | ||
* the filtering is just deferred. | ||
* | ||
* @privateRemarks | ||
* Additional intersections beyond {@link OpaqueJsonSerializable}, | ||
* {@link OpaqueJsonDeserialized}, or intersected matching opaque pair are | ||
* not correctly filtered as need is not expected. | ||
* | ||
* @system | ||
*/ | ||
export type JsonDeserializedOpaqueConversion<T extends AnyOpaqueJsonType, Controls extends FilterControls> = T extends OpaqueJsonSerializable<infer TData, any, unknown> | OpaqueJsonDeserialized<infer TData, any, unknown> ? OpaqueJsonDeserialized<TData, Controls["AllowExactly"], Controls["AllowExtensionOf"]> : "internal error: failed to determine Opaque Json type"; | ||
/** | ||
* Core implementation of {@link JsonDeserialized}. | ||
@@ -577,3 +629,3 @@ * | ||
[K in keyof T]: JsonForDeserializedArrayItem<T[K], Controls, JsonDeserializedRecursion<T[K], Controls, RecurseLimit, TAncestorTypes>>; | ||
} : IsExactlyObject<T> extends true ? Controls["DegenerateNonNullObjectSubstitute"] : IfEnumLike<T> extends never ? T : FlattenIntersection<{ | ||
} : IsExactlyObject<T> extends true ? Controls["DegenerateNonNullObjectSubstitute"] : IfEnumLike<T> extends never ? T : T extends AnyOpaqueJsonType ? JsonDeserializedOpaqueConversion<T, Controls> : FlattenIntersection<{ | ||
[K in keyof T as NonSymbolWithDeserializablePropertyOf<T, Controls["AllowExactly"], Controls["AllowExtensionOf"], K>]: JsonDeserializedRecursion<T[K], Controls, RecurseLimit, TAncestorTypes>; | ||
@@ -580,0 +632,0 @@ } & { |
@@ -10,4 +10,5 @@ /*! | ||
export type { JsonTypeWith, NonNullJsonObjectWith, ReadonlyJsonTypeWith, } from "./jsonType.js"; | ||
export type { OpaqueJsonDeserialized, OpaqueJsonSerializable } from "./opaqueJson.js"; | ||
export type { ShallowReadonly } from "./shallowReadonly.js"; | ||
export type { InternalUtilityTypes, ReadonlySupportedGenerics, } from "./exposedInternalUtilityTypes.js"; | ||
//# sourceMappingURL=exposedUtilityTypes.d.ts.map |
@@ -6,2 +6,3 @@ /*! | ||
export * from "./index.js"; | ||
export type { JsonTypeToOpaqueJson, OpaqueJsonToJsonType } from "./jsonUtils.js"; | ||
import type { DeepReadonly as ExposedDeepReadonly } from "./deepReadonly.js"; | ||
@@ -12,2 +13,3 @@ import type { InternalUtilityTypes as ExposedInternalUtilityTypes } from "./exposedInternalUtilityTypes.js"; | ||
import type { JsonTypeWith as ExposedJsonTypeWith, ReadonlyNonNullJsonObjectWith as ExposedReadonlyNonNullJsonObjectWith } from "./jsonType.js"; | ||
import type { OpaqueJsonDeserialized as ExposedOpaqueJsonDeserialized, OpaqueJsonSerializable as ExposedOpaqueJsonSerializable } from "./opaqueJson.js"; | ||
/** | ||
@@ -42,2 +44,10 @@ * @internal | ||
*/ | ||
export type OpaqueJsonDeserialized<T, Option_AllowExactly extends unknown[] = [], Option_AllowExtensionOf = never> = ExposedOpaqueJsonDeserialized<T, Option_AllowExactly, Option_AllowExtensionOf>; | ||
/** | ||
* @internal | ||
*/ | ||
export type OpaqueJsonSerializable<T, Option_AllowExactly extends unknown[] = [], Option_AllowExtensionOf = never> = ExposedOpaqueJsonSerializable<T, Option_AllowExactly, Option_AllowExtensionOf>; | ||
/** | ||
* @internal | ||
*/ | ||
export declare namespace InternalUtilityTypes { | ||
@@ -44,0 +54,0 @@ type FlattenIntersection<T extends ExposedInternalUtilityTypes.AnyRecord> = ExposedInternalUtilityTypes.FlattenIntersection<T>; |
@@ -87,4 +87,4 @@ /*! | ||
* Specifying `JsonSerializable<unknown>` or `JsonSerializable<any>` yields a type | ||
* alias for {@link JsonTypeWith}`<never>` and should not be used if precise type | ||
* safety is desired. | ||
* alias for {@link JsonTypeWith}`<never>` | {@link OpaqueJsonSerializable}`<unknown>` | ||
* and should not be used if precise type safety is desired. | ||
* | ||
@@ -91,0 +91,0 @@ * Class instances are indistinguishable from general objects by type checking |
@@ -9,2 +9,3 @@ /*! | ||
import type { JsonTypeWith, NonNullJsonObjectWith, ReadonlyJsonTypeWith } from "./jsonType.js"; | ||
import type { OpaqueJsonDeserialized, OpaqueJsonSerializable } from "./opaqueJson.js"; | ||
/** | ||
@@ -323,2 +324,11 @@ * Unique symbol for recursion meta-typing. | ||
/** | ||
* Convenience constraint for any Opaque Json type. | ||
* | ||
* @remarks | ||
* Use in extends check: `T extends AnyOpaqueJsonType` | ||
* | ||
* @system | ||
*/ | ||
export type AnyOpaqueJsonType = OpaqueJsonSerializable<unknown, any, unknown> | OpaqueJsonDeserialized<unknown, any, unknown>; | ||
/** | ||
* Extracts Function portion from an intersection (&) type returning | ||
@@ -440,6 +450,10 @@ * the extracted portion in the `function` property or `unknown` if | ||
AllowExtensionOf: unknown; | ||
} ? Options["AllowExtensionOf"] : never)>; | ||
} ? Options["AllowExtensionOf"] : never)> | OpaqueJsonSerializable<unknown, Options extends { | ||
AllowExactly: unknown[]; | ||
} ? Options["AllowExactly"] : [], Options extends { | ||
AllowExtensionOf: unknown; | ||
} ? Options["AllowExtensionOf"] : never>; | ||
} extends infer Controls ? Controls extends FilterControlsWithSubstitution ? boolean extends (T extends never ? true : false) ? Controls["DegenerateSubstitute"] : Options["IgnoreInaccessibleMembers"] extends "ignore-inaccessible-members" ? JsonSerializableFilter<T, Controls, TAncestorTypes, TNextAncestor> : IfNonPublicProperties<T, { | ||
AllowExactly: Controls["AllowExactly"]; | ||
AllowExtensionOf: Controls["AllowExtensionOf"] | boolean | number | string; | ||
AllowExtensionOf: Controls["AllowExtensionOf"] | boolean | number | string | AnyOpaqueJsonType; | ||
DegenerateSubstitute: Controls["DegenerateSubstitute"]; | ||
@@ -453,2 +467,21 @@ }, "found non-publics", "only publics"> extends "found non-publics" ? T extends readonly (infer _)[] ? { | ||
/** | ||
* Handle Opaque Json types for {@link JsonSerializable}. | ||
* | ||
* @remarks | ||
* {@link OpaqueJsonSerializable} and {@link OpaqueJsonDeserialized} instances | ||
* are limited to `Controls` given context supports. | ||
* `T` from the original Opaque type is preserved. In the case that this now | ||
* produces an improper type such as a `bigint` being let through that is no | ||
* longer supported, then the variance of `Controls` is expected to raise | ||
* the incompatibility error. | ||
* | ||
* @privateRemarks | ||
* Additional intersections beyond {@link OpaqueJsonSerializable}, | ||
* {@link OpaqueJsonDeserialized}, or intersected matching opaque pair are | ||
* not correctly filtered as need is not expected. | ||
* | ||
* @system | ||
*/ | ||
export type JsonSerializableOpaqueAllowances<T extends AnyOpaqueJsonType, Controls extends FilterControlsWithSubstitution> = T extends OpaqueJsonSerializable<infer TData, any, unknown> | OpaqueJsonDeserialized<infer TData, any, unknown> ? T extends OpaqueJsonSerializable<TData, any, unknown> & OpaqueJsonDeserialized<TData, any, unknown> ? OpaqueJsonSerializable<TData, Controls["AllowExactly"], Controls["AllowExtensionOf"]> & OpaqueJsonDeserialized<TData, Controls["AllowExactly"], Controls["AllowExtensionOf"]> : T extends OpaqueJsonSerializable<TData, any, unknown> ? OpaqueJsonSerializable<TData, Controls["AllowExactly"], Controls["AllowExtensionOf"]> : T extends OpaqueJsonDeserialized<TData, any, unknown> ? OpaqueJsonDeserialized<TData, Controls["AllowExactly"], Controls["AllowExtensionOf"]> : "internal error: failed to determine Opaque Json type" : never; | ||
/** | ||
* Essentially a check for a template literal that has $\{string\} or | ||
@@ -492,3 +525,3 @@ * $\{number\} in the pattern. Just `string` and/or `number` also match. | ||
]>>; | ||
} : IsExactlyObject<T> extends true ? NonNullJsonObjectWith<TupleToUnion<Controls["AllowExactly"]> | Controls["AllowExtensionOf"]> : IfEnumLike<T> extends never ? T : FlattenIntersection<{ | ||
} : IsExactlyObject<T> extends true ? NonNullJsonObjectWith<TupleToUnion<Controls["AllowExactly"]> | Controls["AllowExtensionOf"]> : IfEnumLike<T> extends never ? T : T extends AnyOpaqueJsonType ? JsonSerializableOpaqueAllowances<T, Controls> : FlattenIntersection<{ | ||
[K in keyof T as RequiredNonSymbolKeysOf<T, K>]-?: IfPossiblyUndefinedProperty<K, T[K], { | ||
@@ -568,2 +601,21 @@ IfPossiblyUndefined: { | ||
/** | ||
* Handle Opaque Json types for {@link JsonDeserialized}. | ||
* | ||
* @remarks | ||
* {@link OpaqueJsonSerializable} instances are converted to {@link OpaqueJsonDeserialized}. | ||
* The `AllowExactly` and `AllowExtensionOf` properties are set to match the given `Controls`. | ||
* The data type is kept exactly as-is to avoid processing in generic contexts that can't | ||
* produce a meaningful result. The data type should always be filtered through | ||
* {@link JsonDeserialized} when {@link OpaqueJsonDeserialized} is cracked open. So, really | ||
* the filtering is just deferred. | ||
* | ||
* @privateRemarks | ||
* Additional intersections beyond {@link OpaqueJsonSerializable}, | ||
* {@link OpaqueJsonDeserialized}, or intersected matching opaque pair are | ||
* not correctly filtered as need is not expected. | ||
* | ||
* @system | ||
*/ | ||
export type JsonDeserializedOpaqueConversion<T extends AnyOpaqueJsonType, Controls extends FilterControls> = T extends OpaqueJsonSerializable<infer TData, any, unknown> | OpaqueJsonDeserialized<infer TData, any, unknown> ? OpaqueJsonDeserialized<TData, Controls["AllowExactly"], Controls["AllowExtensionOf"]> : "internal error: failed to determine Opaque Json type"; | ||
/** | ||
* Core implementation of {@link JsonDeserialized}. | ||
@@ -577,3 +629,3 @@ * | ||
[K in keyof T]: JsonForDeserializedArrayItem<T[K], Controls, JsonDeserializedRecursion<T[K], Controls, RecurseLimit, TAncestorTypes>>; | ||
} : IsExactlyObject<T> extends true ? Controls["DegenerateNonNullObjectSubstitute"] : IfEnumLike<T> extends never ? T : FlattenIntersection<{ | ||
} : IsExactlyObject<T> extends true ? Controls["DegenerateNonNullObjectSubstitute"] : IfEnumLike<T> extends never ? T : T extends AnyOpaqueJsonType ? JsonDeserializedOpaqueConversion<T, Controls> : FlattenIntersection<{ | ||
[K in keyof T as NonSymbolWithDeserializablePropertyOf<T, Controls["AllowExactly"], Controls["AllowExtensionOf"], K>]: JsonDeserializedRecursion<T[K], Controls, RecurseLimit, TAncestorTypes>; | ||
@@ -580,0 +632,0 @@ } & { |
@@ -10,4 +10,5 @@ /*! | ||
export type { JsonTypeWith, NonNullJsonObjectWith, ReadonlyJsonTypeWith, } from "./jsonType.js"; | ||
export type { OpaqueJsonDeserialized, OpaqueJsonSerializable } from "./opaqueJson.js"; | ||
export type { ShallowReadonly } from "./shallowReadonly.js"; | ||
export type { InternalUtilityTypes, ReadonlySupportedGenerics, } from "./exposedInternalUtilityTypes.js"; | ||
//# sourceMappingURL=exposedUtilityTypes.d.ts.map |
@@ -6,2 +6,3 @@ /*! | ||
export * from "./index.js"; | ||
export type { JsonTypeToOpaqueJson, OpaqueJsonToJsonType } from "./jsonUtils.js"; | ||
import type { DeepReadonly as ExposedDeepReadonly } from "./deepReadonly.js"; | ||
@@ -12,2 +13,3 @@ import type { InternalUtilityTypes as ExposedInternalUtilityTypes } from "./exposedInternalUtilityTypes.js"; | ||
import type { JsonTypeWith as ExposedJsonTypeWith, ReadonlyNonNullJsonObjectWith as ExposedReadonlyNonNullJsonObjectWith } from "./jsonType.js"; | ||
import type { OpaqueJsonDeserialized as ExposedOpaqueJsonDeserialized, OpaqueJsonSerializable as ExposedOpaqueJsonSerializable } from "./opaqueJson.js"; | ||
/** | ||
@@ -42,2 +44,10 @@ * @internal | ||
*/ | ||
export type OpaqueJsonDeserialized<T, Option_AllowExactly extends unknown[] = [], Option_AllowExtensionOf = never> = ExposedOpaqueJsonDeserialized<T, Option_AllowExactly, Option_AllowExtensionOf>; | ||
/** | ||
* @internal | ||
*/ | ||
export type OpaqueJsonSerializable<T, Option_AllowExactly extends unknown[] = [], Option_AllowExtensionOf = never> = ExposedOpaqueJsonSerializable<T, Option_AllowExactly, Option_AllowExtensionOf>; | ||
/** | ||
* @internal | ||
*/ | ||
export declare namespace InternalUtilityTypes { | ||
@@ -44,0 +54,0 @@ type FlattenIntersection<T extends ExposedInternalUtilityTypes.AnyRecord> = ExposedInternalUtilityTypes.FlattenIntersection<T>; |
@@ -87,4 +87,4 @@ /*! | ||
* Specifying `JsonSerializable<unknown>` or `JsonSerializable<any>` yields a type | ||
* alias for {@link JsonTypeWith}`<never>` and should not be used if precise type | ||
* safety is desired. | ||
* alias for {@link JsonTypeWith}`<never>` | {@link OpaqueJsonSerializable}`<unknown>` | ||
* and should not be used if precise type safety is desired. | ||
* | ||
@@ -91,0 +91,0 @@ * Class instances are indistinguishable from general objects by type checking |
{ | ||
"name": "@fluidframework/core-interfaces", | ||
"version": "2.41.0", | ||
"version": "2.42.0", | ||
"description": "Fluid object interfaces", | ||
@@ -79,3 +79,3 @@ "homepage": "https://fluidframework.com", | ||
"@fluidframework/build-tools": "^0.55.0", | ||
"@fluidframework/core-interfaces-previous": "npm:@fluidframework/core-interfaces@2.40.0", | ||
"@fluidframework/core-interfaces-previous": "npm:@fluidframework/core-interfaces@2.41.0", | ||
"@fluidframework/eslint-config-fluid": "^5.7.4", | ||
@@ -82,0 +82,0 @@ "@microsoft/api-extractor": "7.52.8", |
@@ -15,2 +15,3 @@ /*! | ||
import type { JsonTypeWith, NonNullJsonObjectWith, ReadonlyJsonTypeWith } from "./jsonType.js"; | ||
import type { OpaqueJsonDeserialized, OpaqueJsonSerializable } from "./opaqueJson.js"; | ||
@@ -562,2 +563,16 @@ /** | ||
/** | ||
* Convenience constraint for any Opaque Json type. | ||
* | ||
* @remarks | ||
* Use in extends check: `T extends AnyOpaqueJsonType` | ||
* | ||
* @system | ||
*/ | ||
export type AnyOpaqueJsonType = | ||
/* eslint-disable @typescript-eslint/no-explicit-any -- must use `any` for invariant constraint override */ | ||
| OpaqueJsonSerializable<unknown, any, unknown> | ||
| OpaqueJsonDeserialized<unknown, any, unknown>; | ||
/* eslint-enable @typescript-eslint/no-explicit-any */ | ||
/** | ||
* Extracts Function portion from an intersection (&) type returning | ||
@@ -780,11 +795,19 @@ * the extracted portion in the `function` property or `unknown` if | ||
: never; | ||
// There Substitute type could be extracted to helper type, but are kept explicit here | ||
// to make JsonTypeWith show explicitly in results for users, rather | ||
// than either the helper type name or a partially unrolled version. | ||
DegenerateSubstitute: JsonTypeWith< | ||
| (Options extends { AllowExactly: unknown[] } | ||
? TupleToUnion<Options["AllowExactly"]> | ||
: never) | ||
| (Options extends { AllowExtensionOf: unknown } ? Options["AllowExtensionOf"] : never) | ||
>; | ||
// The Substitute type could be extracted to helper type, but is kept explicit here | ||
// to make JsonTypeWith and OpaqueJsonSerializable show explicitly in results for | ||
// users, rather than either the helper type name or a partially unrolled version. | ||
DegenerateSubstitute: | ||
| JsonTypeWith< | ||
| (Options extends { AllowExactly: unknown[] } | ||
? TupleToUnion<Options["AllowExactly"]> | ||
: never) | ||
| (Options extends { AllowExtensionOf: unknown } | ||
? Options["AllowExtensionOf"] | ||
: never) | ||
> | ||
| OpaqueJsonSerializable< | ||
unknown, | ||
Options extends { AllowExactly: unknown[] } ? Options["AllowExactly"] : [], | ||
Options extends { AllowExtensionOf: unknown } ? Options["AllowExtensionOf"] : never | ||
>; | ||
} extends infer Controls | ||
@@ -802,4 +825,10 @@ ? /* Controls should always satisfy FilterControlsWithSubstitution, but Typescript wants a check */ | ||
AllowExactly: Controls["AllowExactly"]; | ||
// Add in primitives that may be branded to ignore intersection classes | ||
AllowExtensionOf: Controls["AllowExtensionOf"] | boolean | number | string; | ||
AllowExtensionOf: | ||
| Controls["AllowExtensionOf"] | ||
// Add in primitives that may be branded to ignore intersection classes | ||
| boolean | ||
| number | ||
| string | ||
// Add in Opaque Json types | ||
| AnyOpaqueJsonType; | ||
DegenerateSubstitute: Controls["DegenerateSubstitute"]; | ||
@@ -833,2 +862,43 @@ }, | ||
/** | ||
* Handle Opaque Json types for {@link JsonSerializable}. | ||
* | ||
* @remarks | ||
* {@link OpaqueJsonSerializable} and {@link OpaqueJsonDeserialized} instances | ||
* are limited to `Controls` given context supports. | ||
* `T` from the original Opaque type is preserved. In the case that this now | ||
* produces an improper type such as a `bigint` being let through that is no | ||
* longer supported, then the variance of `Controls` is expected to raise | ||
* the incompatibility error. | ||
* | ||
* @privateRemarks | ||
* Additional intersections beyond {@link OpaqueJsonSerializable}, | ||
* {@link OpaqueJsonDeserialized}, or intersected matching opaque pair are | ||
* not correctly filtered as need is not expected. | ||
* | ||
* @system | ||
*/ | ||
export type JsonSerializableOpaqueAllowances< | ||
T extends AnyOpaqueJsonType, | ||
Controls extends FilterControlsWithSubstitution, | ||
> = /* eslint-disable @typescript-eslint/no-explicit-any -- must use `any` for invariant constraint override */ | ||
/* infer underlying data type */ T extends | ||
| OpaqueJsonSerializable<infer TData, any, unknown> | ||
| OpaqueJsonDeserialized<infer TData, any, unknown> | ||
? T extends OpaqueJsonSerializable<TData, any, unknown> & | ||
OpaqueJsonDeserialized<TData, any, unknown> | ||
? OpaqueJsonSerializable<TData, Controls["AllowExactly"], Controls["AllowExtensionOf"]> & | ||
OpaqueJsonDeserialized<TData, Controls["AllowExactly"], Controls["AllowExtensionOf"]> | ||
: T extends OpaqueJsonSerializable<TData, any, unknown> | ||
? OpaqueJsonSerializable<TData, Controls["AllowExactly"], Controls["AllowExtensionOf"]> | ||
: T extends OpaqueJsonDeserialized<TData, any, unknown> | ||
? OpaqueJsonDeserialized< | ||
TData, | ||
Controls["AllowExactly"], | ||
Controls["AllowExtensionOf"] | ||
> | ||
: "internal error: failed to determine Opaque Json type" | ||
: never; | ||
/* eslint-enable @typescript-eslint/no-explicit-any */ | ||
/** | ||
* Essentially a check for a template literal that has $\{string\} or | ||
@@ -941,41 +1011,46 @@ * $\{number\} in the pattern. Just `string` and/or `number` also match. | ||
? /* enum or similar simple type (return as-is) => */ T | ||
: /* property bag => */ FlattenIntersection< | ||
{ | ||
/* required properties are recursed and may not have undefined values. */ | ||
[K in keyof T as RequiredNonSymbolKeysOf< | ||
T, | ||
K | ||
>]-?: IfPossiblyUndefinedProperty< | ||
K, | ||
T[K], | ||
{ | ||
IfPossiblyUndefined: { | ||
["error required property may not allow `undefined` value"]: never; | ||
}; | ||
IfUnknownNonIndexed: { | ||
["error required property may not allow `unknown` value"]: never; | ||
}; | ||
Otherwise: JsonSerializableFilter< | ||
T[K], | ||
Controls, | ||
[TNextAncestor, ...TAncestorTypes] | ||
>; | ||
} | ||
>; | ||
} & { | ||
/* optional properties are recursed and, when exactOptionalPropertyTypes is | ||
: /* test for Opaque Json types */ T extends AnyOpaqueJsonType | ||
? /* Opaque Json type => */ JsonSerializableOpaqueAllowances< | ||
T, | ||
Controls | ||
> | ||
: /* property bag => */ FlattenIntersection< | ||
{ | ||
/* required properties are recursed and may not have undefined values. */ | ||
[K in keyof T as RequiredNonSymbolKeysOf< | ||
T, | ||
K | ||
>]-?: IfPossiblyUndefinedProperty< | ||
K, | ||
T[K], | ||
{ | ||
IfPossiblyUndefined: { | ||
["error required property may not allow `undefined` value"]: never; | ||
}; | ||
IfUnknownNonIndexed: { | ||
["error required property may not allow `unknown` value"]: never; | ||
}; | ||
Otherwise: JsonSerializableFilter< | ||
T[K], | ||
Controls, | ||
[TNextAncestor, ...TAncestorTypes] | ||
>; | ||
} | ||
>; | ||
} & { | ||
/* optional properties are recursed and, when exactOptionalPropertyTypes is | ||
false, are allowed to preserve undefined value type. */ | ||
[K in keyof T as OptionalNonSymbolKeysOf< | ||
T, | ||
K | ||
>]?: JsonSerializableFilter< | ||
T[K], | ||
Controls, | ||
[TNextAncestor, ...TAncestorTypes] | ||
>; | ||
} & { | ||
/* symbol properties are rejected */ | ||
[K in keyof T & symbol]: never; | ||
} | ||
> | ||
[K in keyof T as OptionalNonSymbolKeysOf< | ||
T, | ||
K | ||
>]?: JsonSerializableFilter< | ||
T[K], | ||
Controls, | ||
[TNextAncestor, ...TAncestorTypes] | ||
>; | ||
} & { | ||
/* symbol properties are rejected */ | ||
[K in keyof T & symbol]: never; | ||
} | ||
> | ||
: /* not an object => */ never | ||
@@ -1024,3 +1099,3 @@ : /* function => */ never; | ||
: never; | ||
// There Substitute types could be extracted to helper type, but are kept explicit here | ||
// The Substitute types could be extracted to helper type, but are kept explicit here | ||
// to make JsonTypeWith/NonNullJsonObjectWith show explicitly in results for users, rather | ||
@@ -1120,2 +1195,31 @@ // than either the helper type name or a partially unrolled version. | ||
/** | ||
* Handle Opaque Json types for {@link JsonDeserialized}. | ||
* | ||
* @remarks | ||
* {@link OpaqueJsonSerializable} instances are converted to {@link OpaqueJsonDeserialized}. | ||
* The `AllowExactly` and `AllowExtensionOf` properties are set to match the given `Controls`. | ||
* The data type is kept exactly as-is to avoid processing in generic contexts that can't | ||
* produce a meaningful result. The data type should always be filtered through | ||
* {@link JsonDeserialized} when {@link OpaqueJsonDeserialized} is cracked open. So, really | ||
* the filtering is just deferred. | ||
* | ||
* @privateRemarks | ||
* Additional intersections beyond {@link OpaqueJsonSerializable}, | ||
* {@link OpaqueJsonDeserialized}, or intersected matching opaque pair are | ||
* not correctly filtered as need is not expected. | ||
* | ||
* @system | ||
*/ | ||
export type JsonDeserializedOpaqueConversion< | ||
T extends AnyOpaqueJsonType, | ||
Controls extends FilterControls, | ||
> = /* eslint-disable @typescript-eslint/no-explicit-any -- must use `any` for invariant constraint override */ | ||
T extends | ||
| OpaqueJsonSerializable<infer TData, any, unknown> | ||
| OpaqueJsonDeserialized<infer TData, any, unknown> | ||
? OpaqueJsonDeserialized<TData, Controls["AllowExactly"], Controls["AllowExtensionOf"]> | ||
: "internal error: failed to determine Opaque Json type"; | ||
/* eslint-enable @typescript-eslint/no-explicit-any */ | ||
/** | ||
* Core implementation of {@link JsonDeserialized}. | ||
@@ -1168,32 +1272,34 @@ * | ||
? /* enum or similar simple type (return as-is) => */ T | ||
: /* property bag => */ FlattenIntersection< | ||
/* properties with symbol keys or wholly unsupported values are removed */ | ||
{ | ||
/* properties with defined values are recursed */ | ||
[K in keyof T as NonSymbolWithDeserializablePropertyOf< | ||
T, | ||
Controls["AllowExactly"], | ||
Controls["AllowExtensionOf"], | ||
K | ||
>]: JsonDeserializedRecursion< | ||
T[K], | ||
Controls, | ||
RecurseLimit, | ||
TAncestorTypes | ||
>; | ||
} & { | ||
/* properties that may have undefined values are optional */ | ||
[K in keyof T as NonSymbolWithPossiblyDeserializablePropertyOf< | ||
T, | ||
Controls["AllowExactly"], | ||
Controls["AllowExtensionOf"], | ||
K | ||
>]?: JsonDeserializedRecursion< | ||
T[K], | ||
Controls, | ||
RecurseLimit, | ||
TAncestorTypes | ||
>; | ||
} | ||
> | ||
: /* test for matching Opaque Json types */ T extends AnyOpaqueJsonType | ||
? /* Opaque Json type => */ JsonDeserializedOpaqueConversion<T, Controls> | ||
: /* property bag => */ FlattenIntersection< | ||
/* properties with symbol keys or wholly unsupported values are removed */ | ||
{ | ||
/* properties with defined values are recursed */ | ||
[K in keyof T as NonSymbolWithDeserializablePropertyOf< | ||
T, | ||
Controls["AllowExactly"], | ||
Controls["AllowExtensionOf"], | ||
K | ||
>]: JsonDeserializedRecursion< | ||
T[K], | ||
Controls, | ||
RecurseLimit, | ||
TAncestorTypes | ||
>; | ||
} & { | ||
/* properties that may have undefined values are optional */ | ||
[K in keyof T as NonSymbolWithPossiblyDeserializablePropertyOf< | ||
T, | ||
Controls["AllowExactly"], | ||
Controls["AllowExtensionOf"], | ||
K | ||
>]?: JsonDeserializedRecursion< | ||
T[K], | ||
Controls, | ||
RecurseLimit, | ||
TAncestorTypes | ||
>; | ||
} | ||
> | ||
: /* not an object => */ never; | ||
@@ -1200,0 +1306,0 @@ |
@@ -24,2 +24,3 @@ /*! | ||
} from "./jsonType.js"; | ||
export type { OpaqueJsonDeserialized, OpaqueJsonSerializable } from "./opaqueJson.js"; | ||
export type { ShallowReadonly } from "./shallowReadonly.js"; | ||
@@ -26,0 +27,0 @@ |
@@ -13,2 +13,4 @@ /*! | ||
export type { JsonTypeToOpaqueJson, OpaqueJsonToJsonType } from "./jsonUtils.js"; | ||
// Export set of utility types re-tagged as internal for FF client convenience. | ||
@@ -32,2 +34,6 @@ // These types are not intended for direct use by customers and api-extractor will | ||
} from "./jsonType.js"; | ||
import type { | ||
OpaqueJsonDeserialized as ExposedOpaqueJsonDeserialized, | ||
OpaqueJsonSerializable as ExposedOpaqueJsonSerializable, | ||
} from "./opaqueJson.js"; | ||
@@ -79,2 +85,20 @@ // Note: There are no docs for these re-exports. `@inheritdoc` cannot be used as: | ||
*/ | ||
export type OpaqueJsonDeserialized< | ||
T, | ||
Option_AllowExactly extends unknown[] = [], | ||
Option_AllowExtensionOf = never, | ||
> = ExposedOpaqueJsonDeserialized<T, Option_AllowExactly, Option_AllowExtensionOf>; | ||
/** | ||
* @internal | ||
*/ | ||
export type OpaqueJsonSerializable< | ||
T, | ||
Option_AllowExactly extends unknown[] = [], | ||
Option_AllowExtensionOf = never, | ||
> = ExposedOpaqueJsonSerializable<T, Option_AllowExactly, Option_AllowExtensionOf>; | ||
/** | ||
* @internal | ||
*/ | ||
// eslint-disable-next-line @typescript-eslint/no-namespace | ||
@@ -81,0 +105,0 @@ export namespace InternalUtilityTypes { |
@@ -92,4 +92,4 @@ /*! | ||
* Specifying `JsonSerializable<unknown>` or `JsonSerializable<any>` yields a type | ||
* alias for {@link JsonTypeWith}`<never>` and should not be used if precise type | ||
* safety is desired. | ||
* alias for {@link JsonTypeWith}`<never>` | {@link OpaqueJsonSerializable}`<unknown>` | ||
* and should not be used if precise type safety is desired. | ||
* | ||
@@ -96,0 +96,0 @@ * Class instances are indistinguishable from general objects by type checking |
Sorry, the diff of this file is not supported yet
Sorry, the diff of this file is not supported yet
Sorry, the diff of this file is not supported yet
Sorry, the diff of this file is not supported yet
Sorry, the diff of this file is not supported yet
Sorry, the diff of this file is not supported yet
Sorry, the diff of this file is not supported yet
Sorry, the diff of this file is not supported yet
Sorry, the diff of this file is not supported yet
Sorry, the diff of this file is not supported yet
Sorry, the diff of this file is not supported yet
Sorry, the diff of this file is not supported yet
Sorry, the diff of this file is not supported yet
Sorry, the diff of this file is not supported yet
1006646
7.3%277
6.95%10120
7.56%