Problem
The generated Reference<T> type narrows reference to `${T}/${string}`:
// fhir-types/hl7-fhir-r4-core/Reference.ts
export interface Reference<T extends string = string> extends Element {
reference?: `${T}/${string}`;
// ...
}
This rejects other literal reference forms allowed by FHIR:
urn:uuid:<uuid> — transaction Bundle placeholder references (server resolves them on commit)
urn:oid:<oid> — OID-based references
http://example.org/fhir/Patient/123 — absolute URLs
#p1 — fragment references to contained resources
Repro
This is a very common transaction-bundle pattern and it fails under tsc --strict:
import { USCoreBloodPressureProfile } from "./fhir-types/hl7-fhir-us-core/profiles";
import { randomUUID } from "node:crypto";
const patientUrn = `urn:uuid:${randomUUID()}`;
const bp = USCoreBloodPressureProfile.create({
status: "final",
subject: { reference: patientUrn }, // ❌ TS2322: Type 'string' is not assignable to type `Patient/${string}`
});
The profile class's subject field is Reference<"Patient">, so reference is typed as `Patient/${string}` and urn:uuid:... is rejected.
The only current workaround is an inline cast:
subject: { reference: patientUrn as `Patient/${string}` }
...which is a technical lie (the string doesn't actually start with Patient/) and defeats the purpose of the template-literal typing.
Suggested fix
Widen reference to a union that covers all FHIR-valid forms:
reference?:
| `${T}/${string}` // relative
| `http://${string}` // absolute
| `https://${string}` // absolute
| `urn:uuid:${string}` // bundle placeholder
| `urn:oid:${string}` // oid
| `#${string}`; // fragment to contained
This keeps the nice Patient/<id> narrowing for the common case while accepting the other forms. Alternative: fall back to plain string with a JSDoc note, though that loses the typing benefit.
Context
Hit while writing the tutorial "US Core Profiles in TypeScript with @atomic-ehr/codegen" — the tutorial's CSV-to-transaction-Bundle flow uses urn:uuid placeholder references for cross-resource links, which is the canonical FHIR pattern. Working example that reproduces this: developer-experience/atomic-ehr-codegen-typescript-us-core-profiles in HealthSamurai/examples.
Problem
The generated
Reference<T>type narrowsreferenceto`${T}/${string}`:This rejects other literal reference forms allowed by FHIR:
urn:uuid:<uuid>— transaction Bundle placeholder references (server resolves them on commit)urn:oid:<oid>— OID-based referenceshttp://example.org/fhir/Patient/123— absolute URLs#p1— fragment references to contained resourcesRepro
This is a very common transaction-bundle pattern and it fails under
tsc --strict:The profile class's
subjectfield isReference<"Patient">, soreferenceis typed as`Patient/${string}`andurn:uuid:...is rejected.The only current workaround is an inline cast:
...which is a technical lie (the string doesn't actually start with
Patient/) and defeats the purpose of the template-literal typing.Suggested fix
Widen
referenceto a union that covers all FHIR-valid forms:This keeps the nice
Patient/<id>narrowing for the common case while accepting the other forms. Alternative: fall back to plainstringwith a JSDoc note, though that loses the typing benefit.Context
Hit while writing the tutorial "US Core Profiles in TypeScript with @atomic-ehr/codegen" — the tutorial's CSV-to-transaction-Bundle flow uses
urn:uuidplaceholder references for cross-resource links, which is the canonical FHIR pattern. Working example that reproduces this:developer-experience/atomic-ehr-codegen-typescript-us-core-profilesin HealthSamurai/examples.