mirror of
https://github.com/vercel-labs/scriptc.git
synced 2026-10-14 04:39:43 +08:00
79 lines
2.6 KiB
TypeScript
79 lines
2.6 KiB
TypeScript
// JSON over the new element kinds, both directions: record arrays and tuple
|
|
// arrays stringify Node-exactly (tuples as JSON arrays), and checked casts
|
|
// validate parsed text back into typed values — VALID casts only (a valid
|
|
// `as` is a no-op under Node, so the differential harness applies; lying
|
|
// casts live in tests/harness/dyncheck.test.ts). Record fields alphabetical
|
|
// (stringify-parity convention, see 1000-json-stringify-basics.ts).
|
|
interface Entry {
|
|
id: string;
|
|
n: number;
|
|
ok: boolean;
|
|
}
|
|
|
|
const entries: Entry[] = [
|
|
{ id: "a", n: 1, ok: true },
|
|
{ id: "b", n: 2, ok: false },
|
|
];
|
|
console.log(JSON.stringify(entries));
|
|
|
|
// tuples serialize as arrays; tuple arrays as arrays of arrays
|
|
const pt: [number, number] = [3, 4];
|
|
console.log(JSON.stringify(pt));
|
|
const kv: [string, number][] = [
|
|
["one", 1],
|
|
["two", 2],
|
|
];
|
|
console.log(JSON.stringify(kv));
|
|
|
|
// nested: records holding record arrays and tuples
|
|
interface Doc {
|
|
entries: Entry[];
|
|
span: [number, number];
|
|
title: string;
|
|
}
|
|
const doc: Doc = { entries, span: [0, 9], title: "t" };
|
|
console.log(JSON.stringify(doc));
|
|
|
|
// round-trip: parse + checked cast rebuilds typed values
|
|
const back = JSON.parse(JSON.stringify(doc)) as unknown as Doc;
|
|
console.log(back.title, back.entries.length, back.entries[1].id, back.span[1]);
|
|
|
|
const kvBack = JSON.parse('[["x",10],["y",20]]') as unknown as [string, number][];
|
|
console.log(kvBack.length, kvBack[0][0], kvBack[1][1]);
|
|
|
|
// heterogeneous tuple positions round-trip with their own types
|
|
const mixed = JSON.parse('[["m",true,3.5]]') as unknown as [string, boolean, number][];
|
|
console.log(mixed[0][0], mixed[0][1], mixed[0][2]);
|
|
|
|
// null-armed unions inside record-array elements (alphabetical: hint < name)
|
|
interface Slot {
|
|
hint: string | null;
|
|
name: string;
|
|
}
|
|
const slots: Slot[] = [
|
|
{ hint: null, name: "s1" },
|
|
{ hint: "use me", name: "s2" },
|
|
];
|
|
const text = JSON.stringify(slots);
|
|
console.log(text);
|
|
const slotsBack = JSON.parse(text) as unknown as Slot[];
|
|
const secondHint = slotsBack[1].hint;
|
|
console.log(slotsBack[0].hint === null, secondHint === null ? "-" : secondHint);
|
|
|
|
// union-element arrays: distinct record arms discriminated by a shared field
|
|
type Shape =
|
|
| { kind: "circle"; r: number }
|
|
| { h: number; kind: "rect"; w: number };
|
|
const shapes: Shape[] = [
|
|
{ kind: "circle", r: 1 },
|
|
{ h: 2, kind: "rect", w: 3 },
|
|
];
|
|
console.log(JSON.stringify(shapes));
|
|
const shapesBack = JSON.parse(JSON.stringify(shapes)) as unknown as Shape[];
|
|
let area = 0;
|
|
for (const s of shapesBack) {
|
|
if (s.kind === "circle") area += 3 * s.r * s.r;
|
|
else area += s.w * s.h;
|
|
}
|
|
console.log(area);
|