Repository navigation
feat(type-plus): add Serialized and Deserialized - #823
Merged
Merged
Conversation
A branded string that carries the serialized value's type, so a two-line
wrapper gives JSON or flatted a typed round trip. `{ circular: true }` tags
flatted's format; the two formats do not assign to each other either way.
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
🦋 Changeset detectedLatest commit: a8f999f The changes in this PR will be included in the next version bump. This PR includes changesets to release 1 package
Not sure what this means? Click here to learn what changesets are. Click here if you're a maintainer who wants to add another changeset to this PR |
Codecov Report✅ All modified and coverable lines are covered by tests. Additional details and impacted files@@ Coverage Diff @@
## main #823 +/- ##
=========================================
Coverage 100.00% 100.00%
=========================================
Files 39 39
Lines 175 175
Branches 33 33
=========================================
Hits 175 175 ☔ View full report in Codecov by Harness. 🚀 New features to boost your workflow:
|
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Adds
Serialized<T, $O>andDeserialized<S>: a brandedstringthat carries the type of the value it was serialized from, so a two-line wrapper givesJSONor flatted a typed round trip. Types only, no runtime code, no runtime dependency.flatted, before and after
Before: flatted's declarations are
anyin and out.After: two lines of wrapper.
Design
Serialized<T> = string & Branded<Format, T>, reusingBrandedfromsrc/nominal/. The brand name is the format ('Serialized<json>'or'Serialized<circular>'); the brand value isT, soTis covariant:Serialized<{ a: 1 }>assigns toSerialized<{ a: number }>, an unrelated type does not.Serialized.$Options = { circular?: boolean }, defaultfalse, under$StrictOptions.circular: booleanmeans either format. TSDoc says plainly thatcirculartags the format and cannot prove a value is acyclic.T extends JsonCompatible<T>on the type itself and in both wrappers. A recursive type alias and a self-referencing interface compile on all five compilers with no change toJsonCompatible.Deserialized<S extends Serialized<any, { circular: boolean }>>takes either format.IsString<Serialized<T>>istrue(also with{ exact: true }),IsStringLiteralisfalse, matchingBrand<'x', string>.serialized.tsanddeserialized.ts, because both are top-level exports.api/json.mdrather than a new guide; it is the JSON family's page and the reference table lives there.Proof
flatted@3.4.4as an exact devDependency.src/serialized.spec.tsruns the realJSONand flatted through the wrappers: round trips keepT, a cyclic value keeps its cycle through flatted, a cross-format parse is a compile error and at runtime gives the wrong shape (JSON.parse) or throws (flatted.parse), non-JSON values are rejected with the path.Verification
pnpm verify: passpnpm --filter type-plus test:type(all five): passpnpm --filter type-plus test:errors: passpnpm docs:llms:check: up to date🤖 Generated with Claude Code