Skip to content

Commit

Permalink
add refs varaible for jtd validation
Browse files Browse the repository at this point in the history
There seems to be some weird behavior with typescript when refs was left
to default. By specifying it manually the behavior was fixed.

fixes #2167
  • Loading branch information
erikbrinkman committed Jul 30, 2023
1 parent 490eb8c commit 29168a4
Show file tree
Hide file tree
Showing 3 changed files with 56 additions and 3 deletions.
10 changes: 8 additions & 2 deletions lib/core.ts
Original file line number Diff line number Diff line change
Expand Up @@ -340,7 +340,10 @@ export default class Ajv {
validate<T>(schema: Schema | JSONSchemaType<T> | string, data: unknown): data is T
// Separated for type inference to work
// eslint-disable-next-line @typescript-eslint/unified-signatures
validate<T>(schema: JTDSchemaType<T>, data: unknown): data is T
validate<T, R extends Record<string, unknown>>(
schema: JTDSchemaType<T, R>,
data: unknown
): data is T
// This overload is only intended for typescript inference, the first
// argument prevents manual type annotation from matching this overload
validate<N extends never, T extends SomeJTDSchemaType>(
Expand Down Expand Up @@ -371,7 +374,10 @@ export default class Ajv {
compile<T = unknown>(schema: Schema | JSONSchemaType<T>, _meta?: boolean): ValidateFunction<T>
// Separated for type inference to work
// eslint-disable-next-line @typescript-eslint/unified-signatures
compile<T = unknown>(schema: JTDSchemaType<T>, _meta?: boolean): ValidateFunction<T>
compile<T = unknown, R extends Record<string, unknown> = Record<string, unknown>>(
schema: JTDSchemaType<T, R>,
_meta?: boolean
): ValidateFunction<T>
// This overload is only intended for typescript inference, the first
// argument prevents manual type annotation from matching this overload
compile<N extends never, T extends SomeJTDSchemaType>(
Expand Down
2 changes: 1 addition & 1 deletion package.json
Original file line number Diff line number Diff line change
Expand Up @@ -11,7 +11,7 @@
],
"scripts": {
"eslint": "eslint \"lib/**/*.ts\" \"spec/**/*.*s\" --ignore-pattern spec/JSON-Schema-Test-Suite",
"prettier:write": "prettier --write \"./**/*.{json,yaml,js,ts}\"",
"prettier:write": "prettier --write --cache \"./**/*.{json,yaml,js,ts}\"",
"prettier:check": "prettier --list-different \"./**/*.{json,yaml,js,ts}\"",
"test-spec": "cross-env TS_NODE_PROJECT=spec/tsconfig.json mocha -r ts-node/register \"spec/**/*.spec.{ts,js}\" -R dot",
"test-codegen": "nyc cross-env TS_NODE_PROJECT=spec/tsconfig.json mocha -r ts-node/register 'spec/codegen.spec.ts' -R spec",
Expand Down
47 changes: 47 additions & 0 deletions spec/types/jtd-schema.spec.ts
Original file line number Diff line number Diff line change
Expand Up @@ -353,12 +353,30 @@ describe("JTDSchemaType", () => {
})

it("should typecheck ref schemas", () => {
const ajv = new _Ajv()
const refs: JTDSchemaType<number[], {num: number}> = {
definitions: {
num: {type: "float64"},
},
elements: {ref: "num"},
}

// test that ajv.validate captures ref data type
const validData: unknown = [0]
if (ajv.validate(refs, validData)) {
const postValidation: number[] = validData
postValidation[0].should.equal(0)
}
should.not.exist(ajv.errors)

// test that ajv.compile captures ref data type
const validate = ajv.compile(refs)
if (validate(validData)) {
const postValidation: number[] = validData
postValidation[0].should.equal(0)
}
should.not.exist(validate.errors)

const missingDef: JTDSchemaType<number[], {num: number}> = {
// @ts-expect-error
definitions: {},
Expand Down Expand Up @@ -393,6 +411,35 @@ describe("JTDSchemaType", () => {
void [refs, missingDef, missingType, nullRefs, refsNullOne, refsNullTwo]
})

it("should typecheck nested ref schemas", () => {
const ajv = new _Ajv()
const schema: JTDSchemaType<{str: string; ref: number}, {num: number}> = {
definitions: {
num: {type: "int32"},
},
properties: {
ref: {ref: "num"},
str: {type: "string"},
},
}

// test that ajv.validate captures ref data type
const validData: unknown = {str: "", ref: 0}
if (ajv.validate(schema, validData)) {
const validated: string = validData.str
validated.should.equal("")
}
should.not.exist(ajv.errors)

// test that ajv.compile captures ref data type
const validate = ajv.compile(schema)
if (validate(validData)) {
const validated: string = validData.str
validated.should.equal("")
}
should.not.exist(validate.errors)
})

it("should typecheck metadata schemas", () => {
const meta: JTDSchemaType<number> = {type: "float32", metadata: {key: "val"}}
const emptyMeta: JTDSchemaType<unknown> = {metadata: {key: "val"}}
Expand Down

0 comments on commit 29168a4

Please sign in to comment.