rdfjs / types

Authoritative TypeScript typings for all RDFJS specifications
MIT License
17 stars 13 forks source link

Revised Roles and Patterns #24

Open blake-regalia opened 2 years ago

blake-regalia commented 2 years ago

This PR supersedes parts of #23, namely the support of both RDF 1.1 and RDF-star simultaneously. The revised version of this feature no longer introduces any breaking changes.

Instead, the Role and Pattern namespaces expose each term position with an optional generic argument that specifies the mode of RDF to use (and defaults to RDF-star). See code for more details.

If the consensus agrees with this direction, I will follow up with the corresponding test cases as well before suggesting PR for merge.

changeset-bot[bot] commented 2 years ago

⚠️ No Changeset found

Latest commit: 327c78e58f4a24c74614df213cddd42fb5b2e522

Merging this PR will not cause a version bump for any packages. If these changes should not result in a new version, you're good to go. If these changes should result in a version bump, you need to add a changeset.

This PR includes no changesets When changesets are added to this PR, you'll see the packages that this PR includes changesets for and the associated semver types

Click here to learn what changesets are, and how to add one.

Click here if you're a maintainer who wants to add a changeset to this PR

blake-regalia commented 2 years ago

@tpluscode @rubensworks The point of using a string for RDF mode is two-fold. First, it is open for extensibility (AllowedRdfModes is simply there to provide a union term for what RDFJS officially 'supports'). In fact, that was the starting motivation. RDF 1.1, RDF-star, easierRDF, the list goes on. We should strive to be forward compatible with new modes and the string approach is akin to using strings for term types in the spec ('NamedNode', 'BlankNode', etc). Secondly, it enables developers to create for more advanced conditional typings. For example, consider this:

/**
 * `<RdfMode extends AllowedRdfMode=RdfMode_11> => TermTypeKey`
 *
 * Returns the union of valid .termType string values for Terms that appear in the datatype position for the given `RdfMode`
 */
type DatatypeTypeKey<
    RdfMode extends AllowedRdfMode=RdfMode_11,
> = Merge<
    {[K in RdfMode_11 | RdfMode_star]: NamedNodeTypeKey},
    {[K in RdfMode_easier]: DataTypeKey}
>[RdfMode];
tpluscode commented 2 years ago

extends in type param does not work the way I think you expect it to. See this example in TS playground

import { NamedNode, BlankNode, Quad } from 'rdf-js'

type RdfMode_11 = 'rdf-1.1'
type RdfMode_star = 'rdf-star'
type AllowedRdfMode = RdfMode_11 | RdfMode_star

type Subject<
  RdfMode extends AllowedRdfMode=RdfMode_star,
> = NamedNode | BlankNode | (RdfMode extends RdfMode_star? Quad: never)

type RdfStarSubject = Subject<'rdf-star'>

type EasyRdfSubject = Subject<'EasyRDF'>

You cannot add additional types because the constraint literally allows only 'rdf-1.1' and 'rdf-star'

blake-regalia commented 2 years ago

@tpluscode lol, I understand what extends does... see v5 dev here. I think you might have misunderstood the point I am making about extensibility. Forget about AllowedRdfMode for a second.