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

Couple validation with TypeScript typing, vastly improving code effiency of any TypeScript users of this library #448

Open
lukehesluke opened this issue Mar 25, 2024 · 0 comments

Comments

@lukehesluke
Copy link
Contributor

lukehesluke commented Mar 25, 2024

It would be incredible if, when validating e.g. an Opportunity with Data Model Validator, the function could return the data, typed to use the https://github.com/openactive/models-ts Opportunity type. This way, a user could use the library like this:

const result = typedValidateItem(['ScheduledSession', 'Slot'], maybeASlotOrAScheduledSession);
if (!result.isSuccessful) {
  // throw an error or something
}
if (result.opportunity['@type'] === 'ScheduledSession') {
  // This will be typed as a ScheduledSession from models-ts
  const scheduledSession = result.validated;
  // ... do stuff. 
} else {
  // This will be typed as a Slot from models-ts
  const slot = result.validated;
  // ... do stuff.
}

I think it makes sense to create a new function for this, hence typedValidateItem (though feel free to come up with a better name) — especially as it will need a new type signature and has a new param, and may have some limitations to the more generic validate function. It could be implemented like so:

function typedValidateItem<T extends ScheduledSession['type'] | Slot['type'] | SessionSeries['type'] | /* ...etc... */>(
  expectedTypes: T[],
  item: unknown
): { isSuccessful: true, validated: Extract<ScheduledSession | Slot | SessionSeries | /* ...etc... */, { type: T }> } | { isSuccessful: false, errors: ValidationErrors } {
  if (!_.isPlainObject(item)) {
    // return an error
  }
  const type = item['@type'] || item.type;
  if (!expectedTypes.includes(type)) {
    // return an error
  }
  const validationResult = /* Call Validator's validate function */;
  if (validationResultHasErrors(validationResult)) {
    // return an error
  }
  return { isSuccessful: true, validated: item };
}

Ideally it should support every type that Validator supports validating (which might be all OpenActive types? not sure). To start, it would be great if it could support all of the following crucial types:

  • Event
  • ScheduledSession
  • SessionSeries
  • Slot
  • IndividualFacilityUse
  • FacilityUse
  • Order
  • OrderQuote
  • OrderProposal

Caveats

  • The solution outlined above would not support validating an entire RPDE page
  • The TypeScript magic might stop working if the list of possible types grows too large. In which case, we would still benefit from making slightly more specialized functions like: typedValidateOpportunity(..), which would support Event, ScheduledSession, SessionSeries, Slot, IndividualFacilityUse, FacilityUse; typedValidateOrder(..), which would support Order, OrderQuote, OrderProposal, etc.
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

1 participant