TypeSchema/TS: safe parse helpers for ValueSet-bound coded fields#154
Open
TypeSchema/TS: safe parse helpers for ValueSet-bound coded fields#154
Conversation
Add an optional `concepts` field to `BindingTypeSchema` that preserves the
{code, system, display} triples for each enum value. Previously only the bare
code list was stored; system and display were extracted from the ValueSet then
discarded. Generators that want to emit code-to-Coding lookup tables can now
read the concepts directly from the binding instead of re-resolving the
ValueSet.
`bun test --update-snapshots` also reordered the snapshot blocks in introspection.test.ts.snap to match the test source order; that reorder accounts for most of the diff (no content delta).
Add `parseLiteral`, `parseCoding`, `parseBoolean`, `parseNumber`, and `parseInstant` to the runtime helpers asset. These are the building blocks for safely converting external string data (CSV, HTTP form, untyped JSON) into typed FHIR values; per-binding wrappers in the next commit call them with their lookup tables.
For each generated FHIR package, walk the package's resources, complex
types, and profiles to find all referenced ValueSet bindings, then emit a
`bindings.ts` module containing for each binding:
- a `<Binding>Codes` readonly tuple of valid codes (the literal union)
- a `<Binding>` type alias narrowing to that union
- a `<Binding>Concepts` lookup table (code → {system, code, display})
- `parse<Binding>(input)` returning the literal type
- `parse<Binding>Coding(input)` returning a Coding-shaped object filled in
from the lookup table
Both parsers throw with the field name and allowed values when the input
is not in the binding. This eliminates `as` casts on coded fields and
removes the need for callers to re-supply `system` and `display` for
ValueSet-bound Codings.
The per-package bindings module is re-exported from each FHIR package's
index, and `profile-helpers.ts` is now copied whenever bindings (not just
profiles) are emitted, since the parsers depend on it.
- `test/api/write-generator/typescript.test.ts`: assert that the R4 generation emits `bindings.ts` with the expected `AdministrativeGender` codes / concepts / parse helpers, that the package index re-exports the bindings module, and that `profile-helpers.ts` is copied alongside. - `examples/typescript-r4/bindings.test.ts`: end-to-end demo using the generated `parseAdministrativeGender` and `parseAdministrativeGenderCoding` to convert an untyped CSV-like row into a typed Patient.
- Add `bindings.ts` and `export * from "./bindings"` in each FHIR package's index. - Update copied `profile-helpers.ts` with the new `parse*` runtime helpers. - Refresh US Core profile classes (catches up the recently-added static `is()` predicate that the previous regen on this branch missed).
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.
Closes #142.
TypeSchema
BindingTypeSchemacarries an optionalconcepts: Concept[]field with the full{code, system, display}triples extracted from each ValueSet, alongside the existingenum.values(codes only).TS generator
bindings.tsper FHIR package, listing every binding the package's resources / complex types / profiles reference. For each binding it emits:<Binding>Codes— readonly tuple of valid codes<Binding>— literal-union type alias(typeof <Binding>Codes)[number]<Binding>Concepts—Readonly<Record<<Binding>, { system?, code, display? }>>parse<Binding>(input, fieldName?)— narrows a string to the literal type, throws on unknown valuesparse<Binding>Coding(input, fieldName?)— fillssystem/displayfrom the lookup tablebindings.tsis re-exported from each package'sindex.ts.profile-helpers.tsis now copied whenever bindings (not just profiles) are emitted, since the parsers depend onparseLiteral/parseCodingthere.Runtime helpers (
profile-helpers.ts)parseLiteral,parseCoding,parseBoolean,parseNumber,parseInstant. Each throws anErrorwith the field name and allowed values when the input is invalid.Examples
examples/typescript-r4/bindings.test.ts— end-to-end demo using the generated parsers.fhir-types/regenerated to include the newbindings.tsmodule.