Skip to content

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

@lukehesluke

Description

@lukehesluke

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.

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions