Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Replace Require statement with Import statement causing error

I'm trying to use Ajv (and I'm using typescript).

import { Ajv } from "ajv";

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

Just wondering why it is giving this error:

[ts] 'Ajv' only refers to a type, but is being used as a value here.

I'm using it the same as the documentation does:

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

But I use import instead of require so I'm not setting the variable, so i guess this is causing the error. How would I define the variable for usage when using import instead of require?

All code:

import { Injectable } from "@angular/core";
import { Http, Headers, Response } from "@angular/http";
import { Configuration } from "../shared/configuration.model";
import { Observable } from "rxjs/Rx";
import { Ajv } from "ajv";

@Injectable()
export class ValidateJSONSchemaService {

    constructor(private http: Http) { }

    public valJson(json, schemaFile: string) {
        return new Promise((resolve, reject) => {
            this.http.get(schemaFile)
                .toPromise()
                .then(fileContents => fileContents.json())
                .then((schema) => {
                    let ajv = new Ajv({allErrors: true});
                    ajv.validate(schema, json) ? 
                    resolve() :
                    reject(new Error("JSON does not conform to schema: " + ajv.errorsText()));
                }, err => reject(
                    new Error("Unable to get schema file contents:" + err))
                );
        });
    };
}
like image 556
BeniaminoBaggins Avatar asked Dec 01 '22 12:12

BeniaminoBaggins


2 Answers

As @elclanrs said, use import * as Ajv from 'ajv'

Not trying to take credit, but it's been a year and I almost missed the answer because there was nothing marked as the answer.

like image 78
Devin Prejean Avatar answered Dec 10 '22 00:12

Devin Prejean


Just to add in Node 10.x with TS 3.45 and Angular 8.x I had to do it using

// @ts-ignore
import Ajv = require('ajv');

note @ts-ignore as TSlint will complain about importing modules this way

Then later on in my code I could use it as normal.

const ajv = new Ajv();

using import * as Ajv from 'ajv' angular would not build correctly, as I kept seeing this error

 error TS2351: Cannot use 'new' with an expression whose type lacks a call or construct signature.

The Typescript complier recommends therefore you resolve using this import method

 Type originates at this import. A namespace-style import cannot be called or constructed, and will cause a failure at runtime. Consider using a default import or import require here instead.

Hopefully that will help someone else using angular 8.

like image 38
DotMH Avatar answered Dec 10 '22 01:12

DotMH