简体   繁体   English

类型错误:Ajv 不是构造函数

[英]TypeError: Ajv is not a constructor

I have this class where I try to instantiate Ajv with the new keyword and I get this error:我有这个类,我尝试使用 new 关键字实例化Ajv ,但出现此错误:

TypeError: Ajv is not a constructor类型错误:Ajv 不是构造函数

Code:代码:

import * as Ajv from "ajv";

    export class ValidateJsonService {
        validateJson(json, schema) {
            console.log(Ajv);
            let ajv = new Ajv({ allErrors: true });
            if (!ajv.validate(schema, json)) {
                throw new Error("JSON does not conform to schema: " + ajv.errorsText())
            }
        }
    }

The console log:控制台日志:

在此处输入图片说明

This code used to be working and it is how Ajv is used.这段代码曾经有效,这就是 Ajv 的使用方式。 From the Ajv docs:从 Ajv 文档:

The fastest validation call:最快的验证调用:

var Ajv = require('ajv');
var ajv = new Ajv(); // options can be passed, e.g. {allErrors: true}
var validate = ajv.compile(schema);
var valid = validate(data);
if (!valid) console.log(validate.errors);

How come I'm getting this error?我怎么会收到这个错误?

See the bottom of this for how I import the Ajv library - systemjs.config.js:有关我如何导入 Ajv 库的信息,请参阅本文底部 - systemjs.config.js:

(function (global) {
    System.config({
        paths: {
            // paths serve as alias
            'npm:': 'lib/js/'
        },
        // map tells the System loader where to look for things
        map: {
            app: 'app', 
            // angular bundles
            '@angular/core': 'npm:@angular/core/bundles/core.umd.js',
            '@angular/common': 'npm:@angular/common/bundles/common.umd.js',
            '@angular/compiler': 'npm:@angular/compiler/bundles/compiler.umd.js',
            '@angular/platform-browser': 'npm:@angular/platform-browser/bundles/platform-browser.umd.js',
            '@angular/platform-browser-dynamic': 'npm:@angular/platform-browser-dynamic/bundles/platform-browser-dynamic.umd.js',
            '@angular/http': 'npm:@angular/http/bundles/http.umd.js',
            '@angular/router': 'npm:@angular/router/bundles/router.umd.js',
            '@angular/forms': 'npm:@angular/forms/bundles/forms.umd.js',
            // other libraries
            'rxjs': 'npm:rxjs',
            'angular2-in-memory-web-api': 'npm:angular2-in-memory-web-api',
            'angular2-google-maps/core': 'npm:angular2-google-maps/core/core.umd.js',
            'ajv': 'npm:ajv/dist/ajv.min.js',
            'primeng': 'npm:primeng'

I saw that Ajv has a default function so I changed my code to this:我看到 Ajv 有一个默认功能,所以我将代码更改为:

let ajv = new Ajv.default({ allErrors: true });

Not 100% sure what is going on there but it works.不是 100% 确定那里发生了什么,但它有效。

Old question and old answer, but since I think the accepted answer isn't ideal and also leaves unanswered questions, I'm still adding my $.02:旧问题和旧答案,但由于我认为接受的答案并不理想,而且还留下未回答的问题,我仍在添加我的 $.02:

What's causing this is that ajv uses export default or export = syntax, and you're using import * as which imports an object with all exported members from the ajv module, where the default export is a property called default .造成这种情况的原因是ajv使用export defaultexport =语法,并且您使用import * as它导入一个对象,其中包含来自ajv模块的所有导出成员,其中默认导出是一个名为default的属性。

The most reasonable way to import the default constructor function is to use:导入默认构造函数最合理的方式是使用:

import Ajv from 'ajv';
const ajv = new Ajv(...);

rather than而不是

import * as Ajv from 'ajv';
const ajv = new Ajv.default(...); // Ajv is an object containing _all_ exports from the ajv module

If you absolutely feel that you must use import * , then this would at least be cleaner, so that Ajv rather than Ajv.default is the constructor function:如果你绝对觉得你必须使用import * ,那么这至少会更清晰,所以Ajv而不是Ajv.default是构造函数:

import * as AjvModule from 'ajv';
const {default: Ajv} = AjvModule;

If using require rather than import to access exported members from a module that uses export default , it will behave like import * as Ajv , ie, you will get an object with a default property in it.如果使用require而不是import来访问从使用export default的模块导出的成员,它将表现得像import * as Ajv ,即,您将获得一个带有default属性的对象。

So the following are equivalent:所以以下是等价的:

// Pre-ES6 require
const Ajv = require('ajv').default;
const ajv = new Ajv(...);

// Import default
import Ajv from 'ajv';
const ajv = new Ajv(...);

// Import entire module and use default property
import * as Ajv from 'ajv';
const ajv = new Ajv.default(...); // just ugly!

// Import entire module as AjvModule and assign constructor function to Ajv
import * as AjvModule from 'ajv';
const {default: Ajv} = AjvModule;
const ajv = new Ajv(...);

If you do need to import the default export and additional exported members, you can do that without resorting to import * as :如果您确实需要导入默认导出其他导出成员,则无需使用import * as即可做到这一点:

import Ajv, {EnumParams} from 'ajv';
const ajv = new Ajv(...);

Personally I think the accepted answer is somewhat flawed because if you're only interested in importing the ajv constructor function, it makes sense to assign it to the Ajv variable rather than the object that contains the constructor function as a property called default - and then create classes with new Ajv.default syntax - that just looks strange.我个人认为接受的答案有些缺陷,因为如果您只对导入 ajv 构造函数感兴趣,那么将分配给Ajv变量而不是包含构造函数的对象作为名为default的属性是有意义的 - 然后使用new Ajv.default语法创建类 - 这看起来很奇怪。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM