rdfjs / types

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

Plain, Star, Roles, Patterns and Generics #23

Closed blake-regalia closed 2 years ago

blake-regalia commented 3 years ago

This PR addresses several shortcomings of the current typings, introduces a set of narrower 'Plain' types for developers dealing with pre-RDF-star formats such as Turtle 1.1, and includes several fixes for generics, defaults, arguments, and return types. Closes #5

1. Introduction of 'Plain' and 'Star' namespaces

Not all libraries are ready to adopt the RDF-star specification draft and some will be interested in exclusively dealing with RDF 1.1 data. To accommodate the narrower scope of those 'Plain' Term types, this introduces the following namespaces:

1a. PlainRole and StarRole

Unions of Term types for the various roles they play in 'plain' RDF 1.1 Data, and RDF-star data, respectively. Each namespace exports the following named types: Subject, Predicate, Object, Graph, Datatype, and Quad

Note that PlainRole is an export-only type and not used by @rdfs/types internally. It is meant to provide developers with a type for working with serialization formats and datasets that do not (yet) support RDF-star, such as Turtle 1.1 .

1b. PlainPattern and StarPattern

For each type in PlainRole and StarRole, these pattern interfaces add a union with Variable | null for the various RDFJS methods that accept term patterns as input.

2. Addition of PlainQuad and StarQuad

Without removing BaseQuad, these two new interfaces extend BaseQuad by specifying a stricter term type for each quad component than the former Quad_{Subject|Predicate|Object|Graph} interfaces. Most notably, PlainQuad and StarQuad components do not have unions with Variable (those cases are covered separately by PlainPattern and StarPattern).

Note: Each of the Quad_{Subject|Predicate|Object|Graph} interfaces are still made available in the exports and carry the same exact types as before. A deprecation annotation has been added to notify the user to consider using one of the more fitting types.

3. OutQuad now defaults to StarQuad instead of BaseQuad

The specification says that each component of the 'Quad' interface be a Term, hence why BaseQuad exists in the typings. In this PR, OutQuad still extends BaseQuad, meaning that developers may still use quad implementations that have unorthodox term types such as Literal in the subject position. However, this PR makes it so that if the generics arguments are omitted, then OutQuad will default to a quad with the traditional term types (including the RDF-star subject and object types) for each component. This change provides developers with stronger type information by default without removing features nor deviating from the spec.

4. InQuad now defaults to StarQuad instead of OutQuad

InQuad should not default to OutQuad if the 2nd generic argument is omitted. For example:

export class MyDataset extends RDFJS.DatasetCore<MySpecialQuad> {
    // ...
}

Would imply now that the quad parameter is typed to MySpecialQuad for add(quad), delete(quad), has(quad), etc. -- but the library should accept all RDFJS terms as arguments in order to implement the spec, not just MySpecialQuad.

By defaulting to InQuad to StarQuad, if this argument is omitted, then the types for quad arguments are assumed to be traditional, RDF-star compatible quads.

See 3.1, 3.2, 3.3, 3.4, and 3.5 above for code references.

5. subject, predicate, object and graph arguments are now typed to InQuad['{subject|predicate|object|graph}']

Before this change, each argument in match methods (e.g., DatasetCore#match(), Dataset#deleteMatches(), and so on...) were typed to Term. Now these methods are typed by component types within the given generic InQuad argument, and each one is union'ed with | Variable | null.

6. Distinguish between OutQuad vs. InQuad generic arguments for Source and Store

Prior to this PR, the argument types and return type of Source#match() (and, by inheritance, Store#match) were the same; however the implementors should be allowed to accept RDFJS term types as arguments and return a stream of their own implementation of Quad. This change allows implementors to specify those two types (OutQuad and InQuad) much the same way it is done in dataset.d.ts.

Additionally, Store#removeMatches() and Store#deleteGraph() now specify InQuad rather than the ambiguous Q.

7. Remove toArray()

Per https://github.com/rdfjs/dataset-spec/pull/64 .

changeset-bot[bot] commented 3 years ago

⚠️ No Changeset found

Latest commit: b54f46912073add09dd388b5447d43a168e27d11

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

tpluscode commented 3 years ago

Would you revert the rdfjs-tests.d.ts. rename? It did not get picked up by GitHub's diff

blake-regalia commented 3 years ago

Yes, I'm happy to break these out into smaller, more manageable PRs. It's just that several of these changes are intra-dependent so it made it hard to split some of them up.

I understand the veto to 4. InQuad now defaults to StarQuad instead of OutQuad .

tpluscode commented 3 years ago

Yes, I'm happy to break these out into smaller, more manageable PRs. It's just that several of these changes are intra-dependent so it made it hard to split some of them up.

I would totally separate "toArray change".

We may work out the rest. If you look at my branch I linked to, it appears that some of those changes could be avoided?

blake-regalia commented 2 years ago

Closing in favor of new and separate PRs per conversation.