问题 在Angular 2打字稿应用程序中使用moment.js


我正在努力在Angular 2 Typescript应用程序中使用moment.js库。即使在阅读了答案之后 这个问题 我无法让它发挥作用。

这是我到目前为止所做的:

  • 我使用npm安装了moment.js,所以我可以在node_modules / moment / moment.js下找到该库
  • 我配置System.js来检索时刻库:

    System.config({
        packages: {
          app: {
            format: 'register',
            defaultExtension: 'js'
          },
          moment: {
            main: 'moment.js',
            type: 'cjs',
            defaultExtension: 'js'
          }
        },
        map: {
          moment: 'node_modules/moment'
        }
    });
    
  • 我安装了打字稿打字 typings install moment-node --ambient --save 和 typings install moment --ambient --save,所以我可以在typings / main / ambient / moment-node和typings / main / ambient / moment中看到正确的输入

现在,如果在我的代码中我使用 import * as moment from 'moment'; 打字稿编译运行顺利,我可以在Atom编辑器中看到正确的建议(如果我开始 moment(). 我可以看到年(),月()等)。但是,如果我在浏览器中运行我的代码,它会给出一个错误,说'时刻不是一个函数'(调试我可以看到那个时刻是一个有很多方法的对象)。

如果我写 import moment from 'moment'; 浏览器中的代码运行正常,但是打字稿编译失败,“模块时刻没有默认导出”,在编写代码时我无法从Atom获得任何建议。

我究竟做错了什么?在Angular 2打字稿应用程序中导入moment.js(和任何非打字稿库)的正确方法是什么?


4050
2018-02-07 14:11


起源

从'时刻'尝试导入时刻; - Bazinga
感谢您的回复!但是,正如我在回答中所说,如果我写的话 import moment from 'moment'; 打字稿编译失败,使用moment()时我无法从IDE获得任何建议。 - DanyUP


答案:


import * as moment_ from 'moment';
const moment:moment.MomentStatic = (<any>moment_)['default'] || moment_;

4
2018-02-07 15:35



大!这很好用,谢谢!我只是想知道是否有某种方法可以使导入更好。我的意思是:如果moment.js打字稿定义不同,那么就有办法写出moment.default()?如果moment.js主文件不同,那么会有一种方法只写一下()?我在moment.js中发现的问题更多地与它的打字稿定义文件或它的编写方式有关? - DanyUP
这个不对。它有效,但它很丑陋和令人困惑。 TypeScript编译器支持带有标志的SystemJS allowSyntheticDefaultImports。 - Aluan Haddad
这在运行时工作,但不在Visual Studio中编译。 - Eric Grover


正如进一步指出的那样,现在船只有自己的打字。 @ angular / cli也改变了。更新了我的回答以反映这一点。

npm i - 保存时刻

import * as moment from 'moment';

export class SomeClass implements OnInit {

  date: moment.Moment;

  ngOnInit() {
    this.date = moment();
  }

}

就是@ angular / cli所需要的一切。

以下是我过时的答案。

使用angular-cli:所以你在VsCode中获得Intellisense

编辑 - > angular-cli-build.js

module.exports = function(defaults) {
  return new Angular2App(defaults, {
    vendorNpmFiles: [
      ...

      'moment/min/**', // add this line

      ...
    ]
  });
};

编辑 - > system-config.ts

const map: any = {
  moment: 'vendor/moment/min/moment.min.js' // add this line
};

在您的组件中:

import * as moment from 'moment';

...
// example of usage
dates: moment.Moment[] = [];

ngOnInit() {
  let date = moment();
  date.add(2, 'days');
  this.dates.push(date);
}

4
2017-07-08 12:25





我也发现了这个: 使用NPM安装Moment.js:

npm install moment

将其添加到您的SystemJS配置:

map: {
  'angular2': 'node_modules/angular2',
  'rxjs': 'node_modules/rxjs',
  'moment': 'node_modules/moment/moment'
}

您还需要界面: tsd install moment --save 然后添加:

/// <reference path="typings/moment/moment.d.ts" />
import * as moment from 'moment';

1
2018-02-13 19:56



Monent现在提供自己的.d.ts文件。 tsd也被弃用了。 - Aluan Haddad


从index.html添加

 <script src="../node_modules/moment/moment.js"></script>

在您的组件中使用:

declare var moment: any;
...

this.startDate = moment().subtract(15, 'days').format('DD-MM-YYYY');
this.endDate = moment().format('DD-MM-YYYY');

1
2017-11-22 00:24





使用时导入模块 命名空间 用于将导出收集到单个对象的语法,如 import * as moment from 'moment',您不是要导入模块导出的实际时刻对象,而是导入其所有成员。您正在丢失呼叫签名。要解决此问题,请在SystemJS + TypeScript项目中为模块指定值“system”或指定值 true for allowSyntheticDefaultImports,将这些传递给TypeScript编译器,最好是通过 tsconfig.json 文件。 然后像这样导入时刻

import moment from 'moment';

一切都会奏效。


0
2018-05-30 03:28