leafo / tableshape

Test the shape or structure of a Lua table, inspired by React.PropTypes & LPeg
111 stars 9 forks source link

Meaningless Error messages for Discriminated Union Types #11

Closed turbo closed 5 years ago

turbo commented 5 years ago

I have the following type setup:

The two child types represent the success and error object of a given operation, the base type supplies fields which are mandatory for both. The super-type I'm actually using is a union of both child types:

Tfoo_base = {
  type: T.literal "foo"
  time: T.pattern "^%d+%.%w+$"
  protocol: T.one_of({ "tcp", "udp" }) + T.nil / "unknown"
  client: T.string
}

Tfoo_error = T.shape Extend Tfoo_base, {
  error: T.string
}

Tfoo_success = T.shape Extend Tfoo_base, {
  cached: T.boolean + T.nil
  request: T.shape({
    header: Tfoo_request_header
    body: T.array_of Tfoo_request_body
  })
  perf: Tfoo_perf
}

Tevent = T.one_of { Tfoo_success, Tfoo_error }

I was running into an error, where .request.header had extra fields, which is not allowed. However, the error message only printed what it expected, not what it actually got. To solve this, I had to temporarily replace Tevent for Tfoo_success (I knew it was the Tfoo_success variant), at which point it correctly identified an extra field as the culprit.

Note: Extend is just a generic, non-mutating table merge. It doesn't contribute to this issue.

turbo commented 5 years ago

It just occurred to me that one_of can be replaced by +, which is my actual intent.