Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

ThingBase is not exported #29

Closed
rosskevin opened this issue Aug 20, 2019 · 3 comments
Closed

ThingBase is not exported #29

rosskevin opened this issue Aug 20, 2019 · 3 comments

Comments

@rosskevin
Copy link

While trying to use this library with generics, I find most entities extend ThingBase, though it is not exported. I'm trying to extend/enforce our own pattern of use and the lack of export is causing some difficulty.

My suggestion would be to simply all created types, and allow the users to determine how they might want to utilize them.

Here's a short use case:

import { ThingBase } from 'schema-dts'

export type Identified = {
  /**
   * preferably url e.g. https://alienfast.com/#organization
   */
  '@id': string
}

export type WithId<T extends ThingBase> = T & Identified

export function ref<I extends Identified>(i: I): Identified {
  return { '@id': i['@id'] }
}

I figured I would file an issue before taking a look at a PR. Thoughts or concerns?

@Eyas
Copy link
Collaborator

Eyas commented Aug 20, 2019

#28 suggested another use-case where something that looks like this.

My general concern with exporting intermediate types is just that it ties up future development. Right now the API boundary is just the final types (Thing, Person, etc.) and everything in between can change in a breaking way.

As schema-dts matures, I'll be more and more comfortable doing this. Worth looking at this now.

I'm curious, though, why not just use Thing here? It seems like it should just work if WithId was defined as:

export type WithId<T extends Thing> = T & Identified;

That's what we do when we define WithContext right now.

@rosskevin
Copy link
Author

rosskevin commented Aug 20, 2019

But for example Person and Organization do not extend Thing...so how could that be correct?

@Eyas
Copy link
Collaborator

Eyas commented Aug 20, 2019

I wrote up an explanation here about the structure of the type system, but basically, we have something like:

declare type ThingBase = {
    "additionalType"?: URL | URL[];
    "alternateName"?: Text | Text[];
   // ...
};

// This is conceptually true but in practice, it is inlined:
export declare type ThingLeaf = {
    "@type": "Thing";
} & ThingBase;

export declare type Thing = ThingLeaf | Action | CreativeWork | Event | Intangible | MedicalEntity | Organization | Person | Place | Product /* | ... */;

So Thing itself is not just ThingLeaf, but any subsequent child type. The discriminated unions progress recursively to cover all Schema.org types. e.g.

export declare type Organization = OrganizationLeaf | Airline | Consortium | Corporation | EducationalOrganization | FundingScheme | GovernmentOrganization | LibrarySystem | LocalBusiness | MedicalOrganization | NewsMediaOrganization | NGO | PerformingGroup | Project | SportsOrganization | WorkersUnion;

... and so on.

Under the current type system, Person is part of Thing's union, and thus it extends it.

You can try it out with WithContext, which is supplied by schema-dts and you can import it. It's written as such:

export declare type WithContext<T extends Thing> = T & {
    "@context": "https://schema.org";
};

With that, you can write things like:

import { Person, WithContext } from "schema-dts";

const t: WithContext<Person> = {
  "@context": "https://schema.org",
  "@type": "Person", // "Patient" also works here
  "name": "happy"
};

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

2 participants