网站搜索

javascript - 在 Angular 和 TypeScript 中使用 Moment


我刚接触 TypeScript,而且已经有一段时间没有做过认真的 JavaScript 开发了,所以我可能会漏掉一些显而易见的东西。

我正在尝试在一个使用 TypeScript 的 Angular 1 应用中使用 Moment。

我正在使用 Angular 1.6.5、Moment 2.17.1 和 TypeScript 2.17.1。我已经从 npm 安装了 Angular 的类型定义包 @types\angular。在 VS Code 中,Angular 的智能提示等功能可以正常工作。

我已将示例代码发布到 GitHub,链接如下:https://github.com/kevinkuszyk/moment-angular-typescript

第一个错误

我的示例应用在浏览器中运行,但 TypeScript 编译器抱怨找不到 Moment:

app/controller.ts(3,20): error TS2503: Cannot find namespace 'moment'.
app/controller.ts(6,30): error TS2304: Cannot find name 'moment'.

尝试使用 /// 编译器指令

为了解决这个问题,我尝试添加以下 /// 编译器指令:

/// <reference path="../node_modules/moment/moment.d.ts" />

但那并不能修复 TypeScript 编译器:

app/controller.ts(5,20): error TS2503: Cannot find namespace 'moment'.
app/controller.ts(8,30): error TS2304: Cannot find name 'moment'.

导入 Moment

接下来,我尝试按照他们文档中的说明导入 Moment:

import * as moment from 'moment';

但这会导致 TypeScript 生成不同的错误:

app/controller.ts(13,5): error TS2686: 'angular' refers to a UMD global, but the current file is a module. Consider adding an import instead.

导入 Angular

我也导入了 Angular。这修复了 TypeScript:

import * as angular from "angular";

但现在该应用程序无法在浏览器中运行:

Uncaught ReferenceError: require is not defined
    at controller.js:2

使用 Require.JS

最后我尝试添加 Require.JS,但这只是导致了不同的运行时错误:

Uncaught Error: Module name "moment" has not been loaded yet for context: _. Use require([])
http://requirejs.org/docs/errors.html#notloaded
    at makeError (require.js:168)
    at Object.localRequire [as require] (require.js:1433)
    at requirejs (require.js:1794)
    at controller.js:2

问题

  1. 我这里有什么明显的遗漏吗?
  2. 在 npm 上引用随主包一起提供的 d.ts 文件,而不是单独的 @types 包,最佳做法是什么?
  3. 我如何在不使用外部模块加载器的情况下使其工作?

答案#1

看起来这是 Moment 的 d.ts 文件的已知问题(参见问题 #3763、#3808 和 #3663)。

在我们等待官方修复时,这对我有效。

更改:

export = moment;

到这个:

declare module "moment" {
    export = moment;
}

答案#2

尝试在你的 tsconfig.json 文件中将 @types 范围的包显式声明到 typesRoot:

{
    "compilerOptions": {
        "module": "commonjs",
        "target": "es5",
        "noImplicitAny": false,
        "sourceMap": false,
        "typeRoots": [
            "./node_modules/@types"
        ]
    }
}

确保类型定义已正确安装在 node_modules/@types/... 中,并且您的 TypeScript 编译器是最新的。