web-dev-qa-db-ja.com

TypeScriptにVictor.jsをインポートしますか?

TypeScriptプロジェクト(3.0.1)で victor.js ライブラリを使用しようとしていますが、それをインポートして使用しようとすると心が痛くなります。私はそれをタイピング(victor @ types/victor)とともにnpmからインストールしました。無数の方法でインポートしようとしましたが、IDEでタイプ解決と一緒にインポートできないようです。

私はこれらを試しました:

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

(このモジュールは、 'allowSyntheticDefaultImports'フラグをオンにして、そのデフォルトのエクスポートを参照することにより、ECMAScriptインポート/エクスポートでのみ参照できます)

import Victor = require('victor');  

(機能しますが、ecmascriptモジュールを対象とする場合は互換性がありません)

const Victor = require("victor");  

(有効にインポートされ、オブジェクトを構築できますが、入力がありません)

誰かが以前にこれに似た状況に遭遇したと確信しています。それがvictorのindex.jsの先頭に役立つ場合、次の行があります。

exports = module.exports = Victor;
27
radman

簡単に

Es [6]モジュールのようにvictorを使用しようとしていますが、そうではありません。 2つのオプションが表示されます。

  1. モジュールをtsccommonjsのような形式に変換します。この場合、tscvictorとコードの間に必要なグルーロジックを提供します

  2. または、接着剤を提供するモジュールローダーを介してアプリケーションをロードする必要があります。

詳細説明

表示されたインポートで最新のtscを実行すると、次のエラーが発生します。

このモジュールは、「esModuleInterop」フラグをオンにしてデフォルトのエクスポートを参照することにより、ECMAScriptインポート/エクスポートでのみ参照できます。

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のみを使用する場合、コンパイラーにassumeを実行して、 ___importDefault_の作業を行うツールチェーン。そのため、コンパイラーはヘルパーを提供しません。コンパイルを続行できますが、youは、後で___importDefault_と同じ作業を実行するモジュールローダーを使用する責任があります。

37
Louis

さまざまなエラーのデバッグに長い時間を費やしたという点で、私はあなたの心痛を感じます既存のJavaScriptモジュールのTypeScript定義ファイルの書き方そして、ついに私が行き詰まったときの最後のハードルだと思ったものに到達しました同じエラーで:

このモジュールは、 'allowSyntheticDefaultImports'フラグをオンにしてデフォルトのエクスポートを参照することにより、ECMAScriptインポート/エクスポートでのみ参照できます

問題のJavaScript here

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が有効になっている場合でも、moduletargetをいじってみました。インポートステートメントの違い 

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を意味する「Working Version」は、問題なくコンパイルされたようです
  2. Helloworld.ts import {AthenaExpress} from "athena-express";
  3. Helloworld.ts import * as AthenaExpress from "./athena-express";
4
jmunsch

すでにすばらしい回答があったようですが、この短い回答を追加したいと思います。

エラーメッセージ:This module can only be referenced with ECMAScript imports/exports by turning on the 'esModuleInterop' flag and referencing its default export.ts(2497)

自分のJavaScriptファイルをTypeScriptに変換するときに、es5からes6(およびJavaScriptからTypeScript)に移動するときにインポートでこの問題が発生しました。

OtherFile.tsのimport * as File from "./MyFile"のようなインポート。

MyFile.tsファイルでは、最後にexport = {funcName}がありました。

解決策は、MyFile.tsファイルから=をこのようにexport {funcName}から削除することでした。

(これが誰かを助けてくれることを願って、初めてエラー/問題の答えを作ろうとする)

1
Zpeed Tube