woutervh- / typescript-is

Geek Repo:Geek Repo

Github PK Tool:Github PK Tool

Validation Context: Which property is not valid on an object

benwinding opened this issue · comments

Is it possible to determine which property is valid on an object from the AssertType function? Currently I only see Type assertion failed

Something like the following would be helpful:

interface MyRequest {
  name: string,
  age: number
}

try {
  const asString = assertType<MyRequest>(unknownObj);
} catch (e) {
  console.log('error: ', e); // "error: Object does not have property: 'name'   "
}

Hi @benwinding

If I understand correctly you want to have an error message saying what exactly made the validation fail.
This is on the road map https://github.com/woutervh-/typescript-is/blob/master/README.md#%EF%B8%8F-road-map
I will try to make some time for it soon :)

Cheers

Quick note to keep you updated: I have started a branch with the changes needed to achieve this:
https://github.com/woutervh-/typescript-is/tree/validation-detailed-error-message

It's still WIP and will take a bit of time to complete it.

@woutervh- Thank you for putting in the effort! I also think this would be a great feature to have. We use this library for many things, e.g. validating shapes of API requests coming in, but it would be cool to be able to return a detailed validation error to the client.

I started to look into the code in order to implement this, and I was happy to see that there's already some work started on it. If there's any way to help with the implementation (not sure if the task is parallelizable), I'd be happy to.

I've merged the branch and released a new version 0.9.0 0.9.1 0.9.2
The error messages are still rudimentary and a WIP, but should not have any breaking changes, and already add some value for you.

Let me know if it's all working good for you, and any tips on improving the error messages are welcome.
Also feel free to add unit tests for any failing cases.

Here are the tests:
https://github.com/woutervh-/typescript-is/blob/master/test/issue-2.ts

Looks good so far, thanks! Although the error messages are a bit confusing, but that can always be improved - they are helpful even now.

As for tips for improving, take this example code:

import { assertType } from 'typescript-is';

interface Nested {
    a: number;
}

interface Something {
    nested: Nested;
}

assertType<Something>({ nested: { a: "hello" } });

The error message we get is:

at $; cause: at $; cause: at $.nested; cause: at $.nested; cause: at $.nested.a: expected number

However, I think this stack of causes might be unnecessary, just the most nested error message gives all the information, e.g.:

at $.nested.a: expected number

In this example, it's fairly OK as-is; however, the types I myself use can get quite complex (they are usually API request/response shapes), and so the error messages can become hard to parse. Here's an example from a failed validation of a Foursquare API response:

at $; cause: at $; cause: at $.response; cause: at $.response; cause: at $.response.venues; cause: at $.response.venues.[]; cause: at $.response.venues.[]; cause: at $.response.venues.[]: expected 'contact' in object

In this case as well, the most nested message provides all the necessary info:

 at $.response.venues.[]: expected 'contact' in object

Just my 2 cents - thanks again for taking the time to implement this, it's very cool :)

Thanks for the feedback @geomaster
The only reason I included the full stack of causes is in case there is an alternative:

interface A {
  foo: number;
}
interface B: {
  foo: string;
}
type C = A | B;

assertType<C>({foo: true});

In this case the error message is:
at $; all causes: (at $; cause: at $; cause: at $.foo: expected number; at $; cause: at $; cause: at $.foo: expected string)
But you're right, even here it should be enough to just say at $.foo: expected string OR at $.foo: expected number
I'll simplify the messages and check back again.

hi @geomaster

I've made a large refactor and part of the consequences is that the error messages should now be much much simpler and easy to understand.

Please check it out using version 0.10.0 and let me know if you have any feedback.

Closing this issue for housekeeping. If something is wrong with the way the current error messages are generated please re-open or open another ticket.