-
Notifications
You must be signed in to change notification settings - Fork 0
Description
Note
This feature is blocked because TypeScript needs to support partial type inference:
#70 introduces a path in the error message which allows you to see where the parsing error occurred.
{
tag: 'failure'
error: 'not a number',
path: [{
tag: 'object',
key: 'a',
},{
tag: 'array',
index: 0,
}],
}
Which means that data.a[0]
failed to parse.
However, if the user adds their own parsers, they might also want to add their own custom errors that adhere to a different format. For example, they might want to include a different type of path segment that points to an index within a string:
{
tag: 'string',
index: number
}
However, as it stands, they're limited to tags object
and array
. According to this proposal, the path
and error
properties should be removed from the library and replaced by a new property error
:
type ParseFailure<Error> = {
tag: 'failure'
error: Error
}
And:
type ParseResult<Value, Error> = ParseSuccess<Value> | ParseFailure<Error>
(The type parameter should be optional, so that you can write just Parse<?>
.)
The higher order parsers should infer the types of the error messages, just as they infer the type parameter Value
. So you could end up with a nested error that describes all possible failure outcomes; for example, for parsing an object with two properties a: number
and b: string
:
{
tag: 'failure'
error: {
tag: 'object'
errors: {
tag: 'not-an-object',
} | {
tag: 'required-property-missing'
key: 'a'
} | {
tag: 'property-failed'
key: 'a',
error: {
tag: 'parseNumber-failure`
}
} | {
tag: 'required-property-missing'
key: 'b'
} | {
tag: 'property-failed'
key: 'b',
error: {
tag: 'parseString-failure`
}
}
}
}
Or maybe something more easy on the eye?
{
tag: 'failure'
error: {
tag: 'not-an-object'
} | {
tag: 'property-failure'
schema: {
a: {
tag: 'property-missing'
} | {
tag: 'parseNumber-failure'
}
b: {
tag: 'property-missing'
} | {
tag: 'parseString-failure'
}
}
}
}
We could provide function for converting this to a JSON path.
This would work when inferring types, but for explicit type declarations, this would become extremely unergonomic: since TypeScript does not implement partial type inference, the user would need to also specify the second type argument
Cons:
- It will make the API more complicated, thus making it more complicated to extend; especially for higher order parsers. As a compromise, we could provide a default value as the second type parameter
GeneralError
which allows the user to bypass the complex error handling logic. - The size of the error grows with the size of the object.
- Lots of work (but doable), but I don't know if anyone would use this feature.
Questions:
- How are recursive types handled?
- Will anyone ever be interested in the improved errors?