簡體   English   中英

類型錯誤:Ajv 不是構造函數

[英]TypeError: Ajv is not a constructor

我有這個類,我嘗試使用 new 關鍵字實例化Ajv ,但出現此錯誤:

類型錯誤:Ajv 不是構造函數

代碼:

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())
            }
        }
    }

控制台日志:

在此處輸入圖片說明

這段代碼曾經有效,這就是 Ajv 的使用方式。 從 Ajv 文檔:

最快的驗證調用:

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);

我怎么會收到這個錯誤?

有關我如何導入 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'

我看到 Ajv 有一個默認功能,所以我將代碼更改為:

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

不是 100% 確定那里發生了什么,但它有效。

舊問題和舊答案,但由於我認為接受的答案並不理想,而且還留下未回答的問題,我仍在添加我的 $.02:

造成這種情況的原因是ajv使用export defaultexport =語法,並且您使用import * as它導入一個對象,其中包含來自ajv模塊的所有導出成員,其中默認導出是一個名為default的屬性。

導入默認構造函數最合理的方式是使用:

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

而不是

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

如果你絕對覺得你必須使用import * ,那么這至少會更清晰,所以Ajv而不是Ajv.default是構造函數:

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

如果使用require而不是import來訪問從使用export default的模塊導出的成員,它將表現得像import * as Ajv ,即,您將獲得一個帶有default屬性的對象。

所以以下是等價的:

// 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(...);

如果您確實需要導入默認導出其他導出成員,則無需使用import * as即可做到這一點:

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

我個人認為接受的答案有些缺陷,因為如果您只對導入 ajv 構造函數感興趣,那么將分配給Ajv變量而不是包含構造函數的對象作為名為default的屬性是有意義的 - 然后使用new Ajv.default語法創建類 - 這看起來很奇怪。

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM