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

primitive string type disallows picking types from Organization #50

Open
rosskevin opened this issue Nov 20, 2019 · 4 comments
Open

primitive string type disallows picking types from Organization #50

rosskevin opened this issue Nov 20, 2019 · 4 comments

Comments

@rosskevin
Copy link

rosskevin commented Nov 20, 2019

I have built some helper methods to help assemble instances in our common patterns. With the recent introduction of #47, and the fact that none of the Base types are exposed (related: #29 (comment)), I no longer have a way to access/reuse the types of the properties within OrganizationBase model.

With the latest release including #47, I get:

error TS2339: Property 'image' does not exist on type 'Organization'.

5   image: SchemaOrganizationNoRef['image'] | Identified

e.g.

import { Organization as SchemaOrganizationNoRef } from 'schema-dts'
import { Identified } from './Identified'

interface Reffed {
  image: SchemaOrganizationNoRef['image'] | Identified

  /**
   * URL of a logo that is representative of the organization.
   *
   * Additional image guidelines:
   *
   * The image must be 112x112px, at minimum.
   * The image URL must be crawlable and indexable.
   * The image must be in .jpg, .png, or. gif format.
   */
  logo: SchemaOrganizationNoRef['logo'] | Identified
}

/**
 * Allow given properties to be refs
 */
type SchemaOrganization = Omit<SchemaOrganizationNoRef, keyof Reffed> & Reffed

interface Required {
  address: SchemaOrganizationNoRef['address']
  legalName: SchemaOrganizationNoRef['legalName']
  name: SchemaOrganizationNoRef['name']
  /**
   * URL of the organization eg. https://google.com
   */
  url: SchemaOrganizationNoRef['url']
}

/**
 * Declare our `Organization` as a stricter set of properties
 *
 * @see https://schema.org/Organization
 */
export type Organization = Omit<SchemaOrganization, keyof Required> & Required & Identified

export const buildOrganization = (
  o: Omit<Organization, '@id' | '@type'>,
  uniqueName = 'organization',
): Organization => ({
  // '@context': 'https://schema.org',
  '@id': `${o.url}/#${uniqueName}`,
  '@type': 'Organization',
  ...o,
})

for completeness:

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

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

How should I be referencing the declared type of something like Organization['image']?

@Eyas
Copy link
Collaborator

Eyas commented Nov 21, 2019

Yikes, yeah, we should fix that.

@Eyas
Copy link
Collaborator

Eyas commented Nov 21, 2019

FWIW a fix in client code would be:

// Before:
type ImageType = Organization["image"];

// After
type ImageType = (Exclude<Organization, string>)["image"];

@Eyas
Copy link
Collaborator

Eyas commented Nov 21, 2019

(Unrelated, but you don't need Identified or Reffed since v0.4.3, as the @id type is now on Thing and anything that extends it)

@Eyas
Copy link
Collaborator

Eyas commented Nov 22, 2019

If we have a type like:

// From https://stackoverflow.com/a/50375286
type __Flatten<U> = 
  (U extends any ? (k: U)=>void : never) extends ((k: infer I)=>void) ? I : never

type AllSchemaProperties = __Flatten<Exclude<Thing, DataType>>;
export type SchemaProperty = keyof AllSchemaProperties;
export type SchemaRange<TProp extends SchemaProperty> = AllSchemaProperties[TProp];

Where AllSchemaProperties is a flattened-out Thing-like type.

So SchemaRange<"knows"> would give you Person and its sub-types (patient, etc.).

This would be the ideal solution because RDF is property-centric (and you can't have the same property meaning different things on different object).

It's pretty expensive to do though and especially with #34 going on I'm not sure if I should add something like this.

But perhaps a simpler:

export type PropertyOf<
    TSchema,
    TProp extends keyof Exclude<TSchema, DataType>> =
  Exclude<TSchema, DataType>[TProp];

is still helpful.

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