我有一个名为CarType
的枚举,它在一个名为CarType.ts
的文件中。代码如下:
namespace MyProduct.Search {
export enum CarType {
Sedan = 0,
Wagon = 1,
Cabrio = 2,
/* etc */
}
}
在同一目录中名为SearchMain.ts
的另一个文件中,我有以下代码:
/// <reference path="../../d.ts/jquery.d.ts" />
/// <reference path="../../d.ts/knockout.d.ts" />
/// <reference path="../../d.ts/fullcalendar.d.ts" />
namespace MyProduct.Search {
export module SearchMain {
export function Init() {
/* snip */
let type: CarType = CarType.Sedan;
}
/* snip */
}
}
在我尝试导入完整日历类型之前,以上方法工作正常。我在/// reference
行下方添加以下行
import { EventObjectInput } from 'fullcalendar/src/types/input-types';
CarType变得不可用。 Intellisense错误为Property 'CarType' does not exist on type 'typeof Search'
。
如何使用完整日历中的EventObjectInput和代码?
答案 0 :(得分:1)
这是一个令人困惑的问题:
Typescript具有内部模块或名称空间,由关键字namespace
和module
标识。 这两个关键字的含义相同。这是令人困惑的部分,因为module
实际上并不意味着JS模块。
命名空间基本上只是用于实现“显示模块模式”的语法糖。在我们在javascript中使用实际模块之前,我们通常会做这种类型的事情,并且不鼓励使用它。
我建议您查看Typescript游乐场,以了解namespace
关键字在转换为javascript时的实际作用。 (example)
基本上,namespace
只是创建一个对象,您可以在其中控制在对象外部看到的内容。另一个属性是,如果您有两个名称空间声明,并且在同一作用域上具有相同的名称,则合并这些声明。
但最终,它只是在已编译的javascript中作为另一个变量实现。
Typescript还具有“真实”模块,也称为外部模块。实际模块意味着它们是隔离的,您需要某种机制才能在运行时加载它们。如果您的代码打算在node.js中运行,则可以是webpack或browserify,也可以是require
函数,可以是reuqire.js库,但是您需要一些东西。
任何具有顶级 export
或import
语句的文件都是模块。 (在名称空间内导出不是顶级!)
因此,我们有两个选择: 1.文件不是模块。 2.文件是一个模块。
如果文件不是模块,则文件中声明的每个变量/类型都在全局范围内声明。
如果文件是模块,则每个变量/类型的作用域仅限于该文件。
因此,一旦添加:
import { EventObjectInput } from 'fullcalendar/src/types/input-types';
您将SearchMain.ts
转换为外部模块。现在MyProduct.Search
中的命名空间SearchMain.ts
已被隔离,其定义范围不同于CarType.ts
中定义的命名空间。这样您就会出错。
TL; DR-您可以做什么?
将内部模块和外部模块混合在一起很烦人。选一个。 强烈建议仅使用外部模块。不要使用名称空间,只需导入和导出语句即可。迁移代码可能要花一些时间,但这是值得的。
另一个选择是继续使用namespace
。请勿import
EventObjectInput
。使它在其他名称空间上可用。但是同样,不建议这样做。