All files / utils/types TJsonSafe.ts

0% Statements 0/0
0% Branches 0/0
0% Functions 0/0
0% Lines 0/0

Press n or j to go to the next uncovered block, b, p or k for the previous block.

1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31                                                             
/**
 * The JSON-representable form of `T`.
 *
 * `Set` becomes an array and `Map` becomes an array of entry pairs; everything
 * else is structurally unchanged. Because it is a homomorphic mapped type over
 * `keyof T`, a field added to `T` appears here immediately — so a serializer
 * declared to return `TJsonSafe<T>` fails to compile until it writes that field.
 *
 * That is the point. Issue #1225: `IStructSymbolState` gained `pointerTypedefs`
 * and the cache's hand-written capture list did not, which nothing detected.
 *
 * **The guarantee covers required fields only.** A homomorphic mapped type
 * preserves `?`, so an optional field on `T` stays optional here and a
 * serializer may silently omit it — the same defect one `?` away. Wrap the
 * argument in `Required<...>` wherever the compile error is the defense, as
 * `SymbolTable.serializeStructState` does.
 */
type TJsonSafe<T> = T extends string | number | boolean | null | undefined
  ? T
  : T extends ReadonlyMap<infer TKey, infer TValue>
    ? Array<[TJsonSafe<TKey>, TJsonSafe<TValue>]>
    : T extends ReadonlySet<infer TMember>
      ? TJsonSafe<TMember>[]
      : T extends readonly (infer TElement)[]
        ? TJsonSafe<TElement>[]
        : T extends object
          ? { [TProperty in keyof T]: TJsonSafe<T[TProperty]> }
          : T;
 
export default TJsonSafe;