Импортировать Victor.js в TypeScript? - PullRequest
0 голосов
/ 15 февраля 2019

Я пытаюсь использовать библиотеку victor.js в проекте TypeScript (3.0.1), и у меня реальная душевная боль при попытке импортировать и использовать ее.Я установил его из npm вместе с его наборами (victor @ types / victor).Я пытался импортировать его множеством способов, но не могу заставить его импортировать вместе с разрешением типов в моей IDE.

Я пробовал это:

import { Victor} from 'victor';  
import * as v from 'victor'; 

(На этот модуль можно ссылаться только при импорте / экспорте ECMAScript, включив флаг allowSyntheticDefaultImports и указав ссылку на его экспорт по умолчанию)

import Victor = require('victor');  

(работает, но не совместим принацеливание на модули ecmascript)

const Victor = require("victor");  

(импортирует корректно, и я могу создавать объекты, но ни один из типов не присутствует)

Я уверен, что кто-то вышелтам столкнулся с подобной ситуацией до этого.Если это помогает, верхняя часть index.js победителя имеет строку:

exports = module.exports = Victor;

Ответы [ 2 ]

0 голосов
/ 17 марта 2019

Я чувствую вашу душевную боль, в которой я потратил много времени на отладку различных ошибок на , как писать файлы определений машинописи для существующих модулей javascript и, наконец, достиг того, что я думал, было последним препятствием, когда язастрял при той же ошибке:

На этот модуль можно ссылаться только при импорте / экспорте ECMAScript, включив флаг allowSyntheticDefaultImports и указав ссылку на его экспорт по умолчанию

.javascript в вопросе здесь :

module.exports = class AthenaExpress { ...more code.. }

tsconfig.json для компиляции / "Рабочая версия" 1 :

{
  "compilerOptions": {
    "outDir": "dist/",
    "sourceMap": true,
    "noImplicitAny": true,
    "module": "commonjs",
    "target": "es6",
    "jsx": "react"
  },
  "baseUrl": "./src",
  "include": [
    "**/*"
  ],
  "exclude": [
    "node_modules"
  ]
}

"Рабочаяверсия файла d.ts с некоторыми различиями при импорте 2 :

declare module 'athena-express' {
    import * as aws from "aws-sdk";
    interface ConnectionConfigInterface {
        aws: typeof aws,
        s3: string,
        getStats: boolean
    }
    interface QueryResultsInterface {
        Items: any[],
        DataScannedInMB: number,
        QueryCostInUSD: number,
        EngineExecutionTimeInMillis: number,
        Count: number,
    }

    interface QueryInterface {
        sql: string,
        db: string,
    }

    type QueryResult = QueryResultsInterface

    interface AthenaExpressInterface {
        new: (config: ConnectionConfigInterface) => any,
        query: (query: QueryInterface) => QueryResult,
    }

    class AthenaExpress {
        new: (config: ConnectionConfigInterface) => any;
        constructor(config: ConnectionConfigInterface);
        query: (query: QueryInterface) => QueryResult;
    }
}

Версия файла d.ts, получившая такую ​​же ошибку, даже когда была включена esModuleInterop,Я также возился с module и target безрезультатно.Различия в операциях импорта 3 :

import * as aws from "aws-sdk";
interface ConnectionConfigInterface {
    aws: typeof aws,
    s3: string,
    getStats: boolean
}
interface QueryResultsInterface {
    Items: any[],
    DataScannedInMB: number,
    QueryCostInUSD: number,
    EngineExecutionTimeInMillis: number,
    Count: number,
}

interface QueryInterface {
    sql: string,
    db: string,
}

type QueryResult = QueryResultsInterface

interface AthenaExpressInterface {
    new: (config: ConnectionConfigInterface) => any,
    query: (query: QueryInterface) => QueryResult,
}

declare class AthenaExpress {
    new: (config: ConnectionConfigInterface) => any;
    constructor(config: ConnectionConfigInterface);
    query: (query: QueryInterface) => QueryResult;
}

export = AthenaExpress

Примечания:

Расположение файла определения и файл, который я пытался получить, работая сопределение:

 tree src/backend/js
    src/backend/js
        ├── athena-express.d.ts
        └── helloworld.ts
  1. «Рабочая версия», что означает tsc, казалось, компилируется без жалоб
  2. В helloworld.ts import {AthenaExpress} from "athena-express";
  3. В helloworld.tsimport * as AthenaExpress from "./athena-express";
0 голосов
/ 20 февраля 2019

Вкратце

Вы пытаетесь использовать victor, как если бы это был модуль es6, но это не так.Я вижу два варианта:

  1. Позвольте tsc преобразовать ваши модули в формат, подобный commonjs, в этом случае tsc обеспечит необходимую связующую логику между victor и вашим кодом

  2. Или вам нужно загрузить приложение через загрузчик модулей, который обеспечивает клей.

Подробное объяснение

Когда язапустите последнюю версию tsc с указанным импортом, я получаю сообщение об ошибке:

На этот модуль можно ссылаться только при импорте / экспорте ECMAScript, включив флаг 'esModuleInterop' и указав ссылку на негоэкспорт по умолчанию.

Когда я включаю esModuleInterop, то все работает просто отлично.Вот тестовый код, который я использовал:

import Victor from "victor";

const foo = new Victor(1, 2);
console.log(foo.y);

И tsconfig.json:

{
  "compilerOptions": {
    "esModuleInterop": true
  }
}

Проблема возникает из-за того, что когда вы делаете import Victor from "victor", вызапрос значения, которое будет экспортировано с помощью оператора export default..., который является синтаксисом, предоставляемым модулями es6.Однако victor экспортирует все, что соответствует export default....Так что-то должно преодолеть разрыв.С тем, что я показал выше, когда вы компилируете, tsc выдает это:

"use strict";
var __importDefault = (this && this.__importDefault) || function (mod) {
    return (mod && mod.__esModule) ? mod : { "default": mod };
};
exports.__esModule = true;
var victor_1 = __importDefault(require("victor"));
var foo = new victor_1["default"](1, 2);
console.log(foo.y);

Обратите внимание на вспомогательную функцию __importDefault.Он используется всякий раз, когда код TS хочет получить доступ к тому, что модуль экспортирует как export default.... Он проверяет, не претендует ли модуль на модуль es6.Модуль es6, который хочет экспортировать значение по умолчанию, уже правильно структурирован, поэтому ничего не нужно делать, если модуль является модулем es6.Если модуль не является модулем es6, то помощник создает своего рода поддельный модуль, экспортируемым по умолчанию значением которого является значение исходного модуля.

Существует важное предостережение, поскольку вы упоминаете "нацеливание на модули ecmascript".Если вы используете, это tsconfig.json:

{
  "compilerOptions": {
    "esModuleInterop": true,
    "module": "es6"
  }
}

Тогда выдается код:

import Victor from "victor";
var foo = new Victor(1, 2);
console.log(foo.y);

Обратите внимание, что больше нет вспомогательной функции.Это зависит от загрузчика модулей, который будет загружать модули для вашего приложения, чтобы обеспечить ту же логику, что и __importDefault.Если я переименую файл, чтобы он имел расширение mjs, и запустил:

$ node --experimental-modules test.mjs

, я получу такой вывод:

(node:18394) ExperimentalWarning: The ESM module loader is experimental.
2

При использовании Node с поддержкой экспериментального модуля, он обеспечиваетта же функциональность, что и __importDefault.


Когда вы просто используете allowSyntheticDefaultImports без использования esModuleInterop, вы сообщаете компилятору , что предполагается , что в вашем наборе инструментов будет что-то, чтобудет делать работу __importDefault.Таким образом, компилятор не предоставляет помощника.Это позволяет продолжить компиляцию, но вы позже будете ответственны за использование загрузчика модулей, который будет выполнять ту же работу, что и __importDefault.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...