question-mark
Stuck on an issue?

Lightrun Answers was designed to reduce the constant googling that comes with debugging 3rd party libraries. It collects links to all the places you might be looking at while hunting down a tough bug.

And, if you’re still stuck at the end, we’re happy to hop on a call to see how we can help out.

JTDSchemaType has Typescript error with valid JTD

See original GitHub issue

What version of Ajv are you using? Does the issue happen if you use the latest version?

"ajv": "^8.8.2",

** Code and error **

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

// then 

export interface JumpSpec<P = unknown, T = unknown> {
  type: string
  uri: string
  param?: P
  mountAt?: string
  defaults?: T[]           // this array will caus the problem
}

const spec: JTDSchemaType<JumpSpec> = {
  properties: {
    type: { type: 'string' },
    uri: { type: 'string' },
  },
  optionalProperties: {
    param: {},
    mountAt: { type: 'string' },
    defaults: { elements: {} },    // <-- error 
  },
}

Typescript objects to ‘elements’ with : (property) elements: {} Type '{}' is not assignable to type 'never'

Looking at the spec: https://datatracker.ietf.org/doc/html/rfc8927#section-2

I think elements can take the empty form from the CDDL:

   ; All JTD schemas are JSON objects taking on one of eight forms
   ; listed here.
   schema = (
     ref //
     type //
     enum //
     elements //
     properties //
     values //
     discriminator //
     empty //
   )
...

   ; elements describes the "elements" schema form.
   elements = ( elements: { schema }, shared )

Which makes me think it’s a bug 😃

Thanks for your awesome validation library!

Issue Analytics

  • State:closed
  • Created 2 years ago
  • Comments:5 (1 by maintainers)

github_iconTop GitHub Comments

1reaction
erikbrinkmancommented, Jan 15, 2022

What you’re writing makes sense, but is actually nonsense 😅 . Typescript doesn’t allow parametrized types to actually be used, you need to make them “concrete”. In this example, both P and T have default definitions, so you can think of it like:

export interface DefaultJumpSpec2 {
  type: string;
  uri: string;
  param?: Record<string, unknown>;
  mountAt?: string;
  defaults?: Record<string, unknown>[];
}

in JTD, the correct schema for Record<string, unknown> is { values: {} }, thus if you fix your schema to be:

const spec: JTDSchemaType<JumpSpec2> = {
  properties: {
    type: { type: 'string' },
    uri: { type: 'string' },
  },
  optionalProperties: {
    param: {
        values: {}
    },
    mountAt: { type: 'string' },
    defaults: { elements: { values: {} } },
  },
}

it then compiles fine.

Note: this was called out in the error which is saying that {} is missing the key values to be compatible with JTDSchemaType<Record<string, unknown>>.

By not using JTDSchemaType you’re implicitly using JTDDataType under the hood, which should be parsing param and defaults as unknowns instead of as records. That’s fine, but different from the interface you specified.

It’s probably also worth noting that JTD doesn’t have a way to specify Record<string, never> which seems like it was maybe what you intended. For that you’ll need a more powerful verifier (like JSON Schema) to guarantee that there are no keys.

0reactions
MichaelJColecommented, Feb 2, 2022

@epoberezkin @erikbrinkman Thank you, this is super helpful!

Read more comments on GitHub >

github_iconTop Results From Across the Web

Typescript JTD examples fail with "is not assignable to type ...
This is the complete code I am trying to compile. ... No JSON formatted schema is used. The schema is a javascript object...
Read more >
Using with TypeScript - Ajv JSON schema validator
when utility type is used, compiled JTD serializers only accept data of correct type (as they do not validate that the data is...
Read more >
Can i just paste jtd as typescript type syntax? - Stack Overflow
JTDDataType is a utility type from ajv, which converts a jtd schema type to the related valid types in typescript. Security notes:.
Read more >
Learn JSON Typedef in 5 Minutes
JSON Type Definition (aka “JSON Typedef”, or just “JTD”) schemas are just JSON documents ... Technically, only the JSON representation of a schema...
Read more >
TypeScript Type Safety with AJV Standalone
TypeScript (TS) is a statically-typed safe language that outputs ... valid = ajv.validate(schema, data) if (!valid) console.log(ajv.errors).
Read more >

github_iconTop Related Medium Post

No results found

github_iconTop Related StackOverflow Question

No results found

github_iconTroubleshoot Live Code

Lightrun enables developers to add logs, metrics and snapshots to live code - no restarts or redeploys required.
Start Free

github_iconTop Related Reddit Thread

No results found

github_iconTop Related Hackernoon Post

No results found

github_iconTop Related Tweet

No results found

github_iconTop Related Dev.to Post

No results found

github_iconTop Related Hashnode Post

No results found