ostrowr / ts-json-validator

Let JSON play nicely with Typescript
MIT License
342 stars 7 forks source link

.parse is not available on TsjsonParser #10

Closed moltar closed 5 years ago

moltar commented 5 years ago

This:

  public parse = (text: string, skipValidation = false): Validated<T> => {
    const data: unknown = JSON.parse(text);

Gets compiled to:

class TsjsonParser {
    constructor(schema) {
        this.parse = (text, skipValidation = false) => {
            const data = JSON.parse(text);
            if (skipValidation) {
                return data;
            }
            this.validate(data);
            return data;
        };
        this.schema = schema;
        const ajv = new ajv_1.default();
        this.validator = ajv.compile(schema);
    }

And IDE cannot infer this as an available class method.

image
ostrowr commented 5 years ago

That's odd. Which version of TypeScript are you using in your IDE? Intellisense should infer

There's no data anywhere.

I've made a bunch of changes in the last 2 days, can you try latest master and see if you're still running into this issue?

The generated code looks right, but can you check if the generated types match as well? tsjson-parser.d.ts should have something like

export declare class TsjsonParser<T extends SchemaLike> {
    readonly schema: T;
    private readonly validator;
    constructor(schema: T);
    validate(data: unknown): asserts data is Validated<T>;
    parse: (text: string, skipValidation?: boolean) => T[typeof InternalTypeSymbol];
}
moltar commented 5 years ago

You can see this use here, with all of the deps defined in package.json:

https://github.com/moltar/typescript-runtime-type-benchmarks/blob/427f1e18979e38b6c0497a303a564ad379f3cc5b/cases/ts-json-validator.ts#L27

moltar commented 5 years ago

The IDE I'm using is VS Code (latest)

ostrowr commented 5 years ago

Just cloned your repo and was able to replicate.

Looks like you're using Typescript 3.6.4 (which is a totally reasonable thing to be doing.)

However, ts-json-validator currently requires 3.7+ in order to work properly. (As I warn in the README)

When npm-installing in your repo, I get

npm WARN ts-json-validator@0.1.1 requires a peer of typescript@>= 3.7.0 but none is installed. You must install peer dependencies yourself.

Which I think is enough warning – but if you have an idea to make this more obvious, I'd welcome a suggestion/PR!

I've confirmed that this works in the IDE using 3.7 in your repo.

Closing this but feel free to reopen if you think I've missed something.

moltar commented 5 years ago

Ok, thanks for looking into this. What features of TS 3.7 is it relying on that are not available in 3.6.4? Thanks.

moltar commented 5 years ago

Interestingly, after the update, the tests are failing.

export function caseTsJsonValidator(data: Data) {
  return parser.validate(data)
}

It seems return type of the function cannot be inferred and is set to void for some odd reason.

Even though when hovering the return type of validate in IDE, it shows it as a correct return type.

Any ideas?

ostrowr commented 5 years ago

That's due to https://github.com/microsoft/TypeScript/issues/34596

I'm going to change this to a normal type guard for now (so .validate will return true if it validates, and will narrow the type, and false if not.)