1

なぜ他の誰もこの問題を抱えていないのか、それとも私がそれを説明するのに適切な言葉を使っていないだけなのか、少し疑問に思っています。問題は、バージョンが必要な npm に公開するモジュールがあることです。1 つは system-js を介してロードし、npm から直接使用できます。もう 1 つのバージョンは、system-js-builder で作成した自己実行バンドルです。

モジュールが@company/fooと呼ばれていると仮定しましょう 。ルート フォルダーに index.ts があり、src からすべてをエクスポートするだけです。ここには、すべてのサブモジュールがエクスポートされる index.ts もあります。したがって、index.ts は次のようになります。

export * from "./src/";

そして、それを使用したいモジュールでは、次のように簡単に使用できます。

import { bar } from "@company/foo";

ここまでは簡単。いいえ、インデックスから自己実行バンドルを作成し、グローバル名fooを付けて、スクリプトをページに追加するか、他のスクリプトと連結する場合にfoo.bar()を呼び出すことができるようにします。これもうまくいきます。しかし今、このバンドルのタイピングを作成する方法がわからないという問題があります。私の考えは、次のようなことをすることでした

declare namespace foo {
    export * from "./src/";
}

これは、バンドルが何をするかを非常によく説明していると思いました。しかし、typescript はこれを好まない。私もモジュールで何かを試しましたが、何も機能しません。src バレルからエクスポートされたものが名前空間 foo で始まるという事実をどのように説明できますか?

私が達成したいことが明確であることを願っています。

4

2 に答える 2

1

に 2 つのフィールドを追加する必要がありますpackage.json

  1. main-- モジュール ローダーに、 以外のモジュールのエントリ ポイントを通知しますindex.js
  2. typings-- モジュールの TypeScript 定義ファイルを設定します。

たとえば、 に@company/foo次のフィールドを含むモジュールがあるとしますpackage.json

{
    "main": "lib/bundle.js",
    "typings": "index.d.ts"
}

tsconfig.jsonで、次のようにmoduleResolution設定します。

{
    "moduleResolution": "node"
}

からインポートすると@company/foo

import { bar } from '@company/foo';

では、index.d.tsbar を宣言する次の行が必要です。

declare function bar();

barTypeScript は、 の定義からエクスポートされたシンボルを検索しようとしますnode_modules/@company/foo/index.d.ts

アップデート:

別のモジュールから個々の関数/オブジェクトを再エクスポートし、名前空間をエクスポートする完全な例を次に示します。このファイルは、TypeScript によってアンビエント定義として認識されるように、index.d.tsまたはなどと呼ばれる必要があります。main.d.ts

import * as another from './src/another';
declare namespace hello {
  function bar();

  interface ProgrammerIntf {
    work();
    walk();
    play();
  }

  class Programmer implements ProgrammerIntf {
    work();
    walk();
    play();
  }

  export import world = another.world;
}

export default hello;

この名前空間を使用するには、呼び出し元スクリプトで、

import hello from '@company/foo';
hello.bar();
hello.world();
let programmer = new hello.Programmer();

更新 2:

以前は気付かなかったTypeScript のドキュメントでそれを行う方法を見つけました。

global以下のように、スコープ内のすべてのタイプを宣言できます。

import * as another from './src/another';

declare global {
  namespace hello {
    function bar();

    interface ProgrammerIntf {
      work();
      walk();
      play();
    }

    class Programmer implements ProgrammerIntf {
      work();
      walk();
      play();
    }

    export import world = another.world;
  }
}

次に、呼び出し元スクリプトで、次を使用します。

import '@company/foo';
hello.bar();
hello.world();
let programmer = new hello.Programmer();

もちろん、バンドルの最初に宣言をバンドルするとhello、インポートステートメントなしで直接使用できるはずです。

于 2016-12-02T15:41:16.443 に答える
0

私が正しいと理解していればfoo、エクスポートされたすべてのメンバーを持つグローバル変数が必要ですmodule

declare varとでそれを達成できますtypeof

import * as _foo from './src'
declare var foo: typeof _foo
// implement self-executing logic

自己実行コードをインポートすると、コンパイル中のプロジェクト内のすべてのファイルでグローバル変数 foo を使用できるようになります。

JavaScript ファイルの場合、アクセスできるロジックを実装している限り、型認識は行われませんfoo

于 2016-12-07T11:40:24.120 に答える