feat: DatasetWrapper helpers return T & Quad_Subject / T & Quad_Object - #87
Draft
jeswr wants to merge 2 commits into
Draft
feat: DatasetWrapper helpers return T & Quad_Subject / T & Quad_Object#87jeswr wants to merge 2 commits into
jeswr wants to merge 2 commits into
Conversation
Adds an overloaded public static from(term, dataset, factory) to TermWrapper that is runtime-equivalent to the constructor but returns the intersection of the (sub)class instance type and the RDF/JS term type of the wrapped term (NamedNode when a string IRI is passed, the inferred term type otherwise). Instances created this way can be passed directly to factory.quad(), dataset.match() and any other RDF/JS Term position without casts. Fully non-breaking: the constructor and the existing typed getters are untouched. Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
…helpers Constrains the generics of subjectsOf/objectsOf/instancesOf/ matchSubjectsOf/matchObjectsOf to T extends TermWrapper and intersects the results with the matched term type, so they can be used anywhere an RDF/JS term is expected without casts. Results are constructed via the TermWrapper.from static factory, which carries the term type into the instance type. ITermWrapperConstructor is tightened to the static side of a TermWrapper subclass (constructor signature plus the inherited from factory) and TermAs.instance picks up the matching constraint. Runtime behaviour is unchanged. Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
This was referenced Jul 6, 2026
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.
Types the results of the
DatasetWrappernavigation helpers as both the mapping class and the matched term.What it does
subjectsOf,instancesOfandmatchSubjectsOfnow returnIterable<T & Quad_Subject>, andobjectsOfandmatchObjectsOfreturnIterable<T & Quad_Object>, with the generics constrained toT extends TermWrapper. Results can be passed directly anywhere an RDF/JS term is expected —factory.quad(…),dataset.match(…)— without casts, and the compiler rejects impossible uses (a matched subject as aLiteral, a matched object as aQuad_Subject, …).TermWrapper.fromstatic factory (feat: TermWrapper.from static factory with intersection return type #83) instead ofnew, which is what carries the matched term's type into the instance type.ITermWrapperConstructor<T>is tightened to the static side of aTermWrappersubclass: the familiar constructor signature intersected withPick<typeof TermWrapper, "from">, withTconstrained (and defaulted) toTermWrapper. Any class deriving fromTermWrappersatisfies it automatically because the staticfromis inherited; classes that merely copy the constructor signature no longer do.TermAs.instancepicks up the matchingT extends TermWrapperconstraint.Runtime behaviour is unchanged:
fromdelegates to the constructor.Stacked on #83
The helpers call
TermWrapper.from, so this branch includes #83's commit; until #83 merges, it shows up in this diff too. Reviewing/merging #83 first reduces this PR to the singleDatasetWrapper/ITermWrapperConstructorcommit.Relation to #61/#74
Supersedes the dataset-typing slice of #61: the
DatasetWrapperhelper signatures, theITermWrapperConstructortightening, and itstest/unit/dataset_wrapper_types.test.ts. One deliberate difference: #61's version of that test asserted thatLiteral/Quadmembers (.language,.subject, …) do not exist on the results, which relies on #61's restructuring of theTermWrappergetters — the contested slice that #85 deliberately leaves out. On top of the currentTermWrapperthose members remain present on every wrapper, so the ported test instead pins down exactly what this slice adds: results are assignable toQuad_Subject/Quad_Objectwithout casts, and@ts-expect-errorproves they are notLiteral/Quad_Predicate/Quad_Subjectwhere the position rules that out. Should the getter restructuring land later, strengthening these tests to #61's assertions is a small follow-up.Testing
test/unit/dataset_wrapper_types.test.ts: runtime assertions for all five helpers (result counts, mapping-class members) plus compile-level assertions checked bytsc -p test— positive (results used as subject/object terms infactory.quadandmatchwithout casts) and negative (@ts-expect-errorfor invalid positions;ITermWrapperConstructorsatisfied by theParent/Childmodels, rejected for a structurally similar class that does not derive fromTermWrapper).test/unit/model/ParentDataset.tsgetters updated to the intersection return types (covariant, so the existingdataset_wrapper.test.tsis unchanged).npm test: 149 tests, 0 fail (5 pre-existing skips).npx typedoc: 0 errors, 6 warnings — identical tomain.npm audit --omit=dev --audit-level=moderate: 0 vulnerabilities.