ajv icon indicating copy to clipboard operation
ajv copied to clipboard

Syntax for Ajv import?

Open ajvincent opened this issue 3 years ago • 9 comments

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

Version 8.11.0, installed today

Ajv options object None.

Your code

// ProjectJSON.mts

// this works, https://github.com/microsoft/TypeScript/issues/24847}
import { default as Ajv } from "ajv";

// this doesn't work, but is the currently recommended import line
//import Ajv from "ajv";
/*
_02_passthrough_types/source/ProjectJSON.mts(98,17): error TS2351: This expression is not constructable.
  Type 'typeof import("/home/ajvincent/code-generation/cross-stitch/node_modules/ajv/dist/ajv")' has no construct signatures.
*/
const ajv = new Ajv();
void(ajv);

I was bitten on this exact error with https://github.com/dsherret/code-block-writer/issues/42 a few weeks ago.

Are you going to resolve the issue?

I can, by adding a little bit of documentation. I just need to know where people want it, if they don't want to quickly fix this themselves.

ajvincent avatar Jul 27 '22 01:07 ajvincent

difficult to say what is incorrect without seeing your TS configuration.

import Ajv from "ajv" works with the TS config that ajv uses - please check it.

epoberezkin avatar Aug 03 '22 20:08 epoberezkin

difficult to say what is incorrect without seeing your TS configuration.

import Ajv from "ajv" works with the TS config that ajv uses - please check it.

Here's what I have:

{
  "compilerOptions": {
    "lib": ["es2022"],
    "module": "es2022",
    "target": "es2022",
    "moduleResolution": "node",
    "sourceMap": true,
    "declaration": true,

    "experimentalDecorators": true
  },

  "exclude": [
    "spec/**"
  ],

  "extends": "@tsconfig/node16/tsconfig.json"
}

The file is https://github.com/ajvincent/cross-stitch/blob/main/_02_passthrough_types/source/ProjectJSON.mts

ajvincent avatar Aug 03 '22 21:08 ajvincent

This configuration works for me:

{
    "compilerOptions": {
        "esModuleInterop": true,
        "module": "node16",
        "moduleResolution": "node",
        "sourceMap": true,
        "strict": true
    }
}

Maybe both esModuleInterop and moduleResolution are required?

XC-Zhang avatar Aug 12 '22 12:08 XC-Zhang

 import { default as Ajv } from 'ajv'

The above was needed whenever your project was targeting ESM output from typescript. i.e. moduleResolution = NodeNext/Node16+ and module = NodeNext/Node16+.

With typescript 4.8.3 the above actually stopped working and started producing a different type error for me. I stumbled across this comment on a typescript issue. It seems typescript is pointing blame on the libraries being incorrectly typed for whatever reason.

To fix my error I had to switch back to

import Ajv from 'ajv'

and then when I go and try to use the Ajv class it is actually something like

 const ajv = new Ajv.default()

kalvenschraut avatar Sep 09 '22 03:09 kalvenschraut

I can confirm that the normal import doesn't work when using moduleResolution node16 or nodenext. We are currently using the following workaround:

import AjvModule from 'ajv'

// FIXME: https://github.com/ajv-validator/ajv/issues/2047
const Ajv = AjvModule.default

LinusU avatar Nov 08 '22 12:11 LinusU

In TypeScript 5.0, you can set moduleResolution to bundler to solve the problem of editor error. However, this mode is provided to allow tools such as vite to decide the module packaging method independently. The result of my compilation under esm can run normally. It is not clear whether other people's code can use this repair method.

My tsconfig.json content:

{
  "compilerOptions": {
    /* Modules */
    "module": "ES2022",                                  /* Specify what module code is generated. */
    "moduleResolution": "bundler",                       /* Specify how TypeScript looks up a file from a given module specifier. */
    ...
  }
}

pboymt avatar Apr 24 '23 07:04 pboymt