Skip to content

doc: Fix JTD typescript sample error #1562

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Merged
merged 2 commits into from
Apr 26, 2021

Conversation

ktrueda
Copy link
Contributor

@ktrueda ktrueda commented Apr 23, 2021

What issue does this pull request resolve?

JTD sample code for typescript does not work. tsc couldn't compile it.

ajv: 8.1.0
typescript: 4.2.4

import Ajv, {JTDSchemaType} from "ajv/dist/jtd"
const ajv = new Ajv()

interface MyData = {
  foo: number
  bar?: string
}

const mySchema: JTDSchemaType<MyData> = {
  properties: {
    foo: {type: "int32"} // any JTD number type would be accepted here
  },
  optionalProperties: {
    bar: {type: "string"}
  }
}
$ npx ts-node src/main.ts
⨯ Unable to compile TypeScript:
src/main.ts:5:8 - error TS2693: 'number' only refers to a type, but is being used as a value here.

5   foo: number
         ~~~~~~
src/main.ts:6:3 - error TS2304: Cannot find name 'bar'.

6   bar?: string
    ~~~
src/main.ts:6:9 - error TS2693: 'string' only refers to a type, but is being used as a value here.

6   bar?: string
          ~~~~~~
src/main.ts:10:3 - error TS2322: Type '{ properties: { foo: { type: string; }; }; optionalProperties: { bar: { type: string; }; }; }' is not assignable to type 'JTDSchemaType<MyData, Record<string, never>>'.
  Object literal may only specify known properties, and 'properties' does not exist in type 'JTDSchemaType<MyData, Record<string, never>>'.

10   properties: {
     ~~~~~~~~~~~~~
11     foo: {type: "int32"} // any JTD number type would be accepted here
   ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
12   },
   ~~~
src/main.ts:4:18 - error TS1005: '{' expected.

4 interface MyData = {
                   ~
src/main.ts:6:7 - error TS1109: Expression expected.

6   bar?: string
        ~

What changes did you make?

  1. Use valid syntax for interface
  2. Not use JTDSchemaType

After fixing it. I think that it work.

import Ajv from "ajv/dist/jtd"
const ajv = new Ajv()

interface MyData {
  foo: number
  bar?: string
}

const mySchema = {
  properties: {
    foo: {type: "int32"} // any JTD number type would be accepted here
  },
  optionalProperties: {
    bar: {type: "string"}
  }
}

const serializeMyData = ajv.compileSerializer(mySchema);
console.log(serializeMyData({foo: 123}));
$ npx ts-node src/main.ts
{"foo":123}

Is there anything that requires more attention while reviewing?

Verified

This commit was signed with the committer’s verified signature.
renovate-bot Mend Renovate
const ajv = new Ajv()

interface MyData = {
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

this is indeed a typo ...

docs/api.md Outdated
foo: number
bar?: string
}

const mySchema: JTDSchemaType<MyData> = {
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

... but without explicitly defining schema type, the serializer would not check data type, as the comment below says - why is it removed here?

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

When I use typescript code below, tsc couldn't compile it.

import Ajv, {JTDSchemaType} from "ajv/dist/jtd"
const ajv = new Ajv()

interface MyData {
  foo: number
  bar?: string
}

const mySchema: JTDSchemaType<MyData> = {
  properties: {
    foo: {type: "int32"} // any JTD number type would be accepted here
  },
  optionalProperties: {
    bar: {type: "string"}
  }
}

const serializeMyData = ajv.compileSerializer(mySchema)
$ npx ts-node src/main.ts
⨯ Unable to compile TypeScript:
src/main.ts:11:11 - error TS2322: Type 'string' is not assignable to type 'never'.

11     foo: {type: "int32"} // any JTD number type would be accepted here
             ~~~~
src/main.ts:14:11 - error TS2322: Type 'string' is not assignable to type 'never'.

14     bar: {type: "string"}
             ~~~~

But when I use code below, tsc could compile it.
Plus I thought the result may be correct.
I'm not so confident since I am beginner here.

import Ajv, {JTDSchemaType} from "ajv/dist/jtd"
const ajv = new Ajv()

interface MyData {
  foo: number
  bar?: string
}

// const mySchema: JTDSchemaType<MyData> = {
const mySchema = {
  properties: {
    foo: {type: "int32"} // any JTD number type would be accepted here
  },
  optionalProperties: {
    bar: {type: "string"}
  }
}

const serializeMyData = ajv.compileSerializer(mySchema)
console.log(serializeMyData({"foo": "123", "baz": 123})); // => {"foo":123}
console.log(serializeMyData({"foo": "123"})); // => {"foo":123}
console.log(serializeMyData({})); // => {"foo":undefined}

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

There can be two reasons - typescript prior to 4.2.3 or not set strictNullChecks

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

From the error message the latter seems more likely

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I tried unset strictNullChesk. But it didn't work.

tsconfig.json

{
  "compilerOptions": {
    "strictNullChecks": false
  }
}
$ npx ts-node --project /path/to/tsconfig.json src/main.ts
⨯ Unable to compile TypeScript:
src/main.ts:12:11 - error TS2322: Type 'string' is not assignable to type 'never'.

12     foo: {type: "int32"} // any JTD number type would be accepted here
             ~~~~
src/main.ts:15:11 - error TS2322: Type 'string' is not assignable to type 'never'.

15     bar: {type: "string"}
             ~~~~

I tried to use older version of typescript. It didn't work either.
Since I can't understand why, should I revert the type change of mySchema ?

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

strictNullChecks should be true - I will check the example a bit later

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Typescript should be at least 4.2.3, not older

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

You can also use it without schema type, and explicitly pass type parameter to compileSerializer

Copy link
Contributor Author

@ktrueda ktrueda Apr 25, 2021

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Thank you for your help. It worked.

{
  "compilerOptions": {
    "strictNullChecks": true
  }
}
import Ajv, {JTDSchemaType} from "ajv/dist/jtd"
const ajv = new Ajv()

interface MyData {
  foo: number
  bar?: string
}

const mySchema: JTDSchemaType<MyData> = {
// const mySchema = {
  properties: {
    foo: {type: "int32"} // any JTD number type would be accepted here
  },
  optionalProperties: {
    bar: {type: "string"}
  }
}

const serializeMyData = ajv.compileSerializer(mySchema)
console.log(serializeMyData({foo: 123, bar: "str"})); // => {"foo":123,"bar":"str"}
console.log(serializeMyData({foo: 123})); // => {"foo":123}

I'll fix the code change.

@epoberezkin epoberezkin merged commit d3bef59 into ajv-validator:master Apr 26, 2021
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Development

Successfully merging this pull request may close these issues.

None yet

2 participants