web-dev-qa-db-ja.com

サイトが既にmoment.min.jsを使用している場合、Moment.js TypeScript定義ファイルを使用するにはどうすればよいですか?

TypeScriptを使用するようにWebサイトを変換している最中で、多くのJavaScriptファイルの1つだけをTypeScriptに変換しています。私のサイトのすべてのページは既に以下のようなmoment.jsを参照しています。

<script src="/scripts/moment.min.js"></script>

他のTypeScript定義ファイルを追加しました。

npm install --save-dev @types/jquery

...しかし、上記は今のところ間違った選択のようです。上記のコマンドを使用すると(ただし、 'jquery'を 'moment'に置き換えます)、次のようなreadmeファイルがダウンロードされます。

これは、モーメント( https://github.com/moment/moment )のスタブ型定義です。 Momentは独自のタイプ定義を提供するため、@ types/momentをインストールする必要はありません。

解決策として、GitHubリポジトリからmoment.d.tsファイルを保存し、TypeScriptファイルでそのように参照してみました。

///<reference path="../../Scripts/typeDeclarations/moment.d.ts"/>
var now:any = moment.utc();

しかし、TypeScriptは私に警告を与えます:

「モーメント」という名前が見つかりません

16
edt

これを行う1つの方法は、カスタムタイピングを作成することです。 custom-typings/moment.d.ts

export * from 'moment'
export as namespace moment

そして、そのフォルダをtsconfig.json

{
  include: [
    "custom-typings"
  ]
}
7
unional

TL; DR;

Githubサイトからプロジェクトに moment.d.tslink )を追加し、コメントアウト最後の行

 //export = moment;

これを証明するためのミニテストプロジェクトを作成しました。

プロジェクトの構造

--
  |
  -typings/
     -moment/
       -moment.d.ts   <-- //export = moment; commented out
  -TypeScript/
     -main.ts
  -tsconfig.json

typingsTypeScriptの両方の内容はコンパイルターゲットの一部です。つまり、tsconfig.jsonで除外されていません。

{
    "compilerOptions": {
        "target": "es5",
        "declaration": false,
        "noImplicitAny": true,
        "removeComments": true,
        "outDir": "dist",
        "jsx": "react",
        "sourceMap": true,
        "experimentalDecorators": true
    },
    "compileOnSave": true,
    "exclude": [
        "node_modules",
        "dist"
    ]
}

main.tsファイルには

const now: moment.Moment = moment.utc();

コンパイルします...予想どおり、my IDEは定義ファイルからオートコンプリートを提供します(///<referenceタグは必要ありません-とにかく避けてください)

定義ファイルの最後にあるexportステートメントを削除すると、それが内部(ただしグローバル)モジュール宣言ファイルに「変換」されます。

9
Bruno Grieder

残念ながら、momentjsタイプの宣言は純粋にモジュール式の構文で記述されています。これは、最近、多くの人々がnpmを使用してjsパッケージを取得し、WebpackやBrowserifyなどのモジュールローダーを使用して、ブラウザーで使用できる形式でnpmモジュールをバンドルしているためです。

あなたのケースでは、モジュールを使用していませんが、グローバルコンテキストでのブラウザースクリプトのインポートに依存しています。これをサポートするには、定義ファイルの作成者はUMDガイドラインに従って定義を行う必要があります。これは、モジュール式とグローバルアンビエントの両方の使用をサポートするように定義を記述する方法です。

幸い、これを定義のコピーに追加するのは非常に簡単です。次の行をmoment.d.tsの先頭に追加するだけです

export as namespace moment;

これは基本的に、トリプルスラッシュディレクティブでmoment.d.tsを参照しているときに、「moment」という名前のグローバル名前空間の下でモジュールからエクスポートされたすべてを利用できるようにするということです。

これは、グローバルコンテキストでアクセス可能なグローバルmoment変数が存在し、Cannot find the name 'moment'エラーが表示されなくなったことを意味します。

これで十分です。

6
dtabuenc

バージョン2.13.0以降、MomentにはTypeScript定義ファイルが含まれています。したがって、このバージョンを使用している場合は、以下を実行できます。

import * as moment from 'moment';


let now = moment().format('LLLL');

:インポートに問題がある場合は、追加"allowSyntheticDefaultImports": true in compilerOptions in your tsconfig.jsonファイル。

参考までに、公式の doc にアクセスしてください。

1
Hitesh Kumar