导入模块会中断本地类型,而类型上不存在属性



我有一个名为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';

车辆类型变得不可用。智能感知错误Property 'CarType' does not exist on type 'typeof Search'

如何在代码中使用来自完整日历的事件对象输入?

这是一个令人困惑的问题:

Typescript 具有内部模块或命名空间,由关键字namespacemodule标识。这两个关键字具有相同的含义。这是令人困惑的部分,因为module实际上并不意味着JS模块。 命名空间基本上只是用于实现"揭示模块模式"的语法糖。这是我们在javascript中拥有实际模块之前曾经做的事情,并且不鼓励使用它。

我建议查看 Typescript 游乐场,以了解namespace关键字在转换为 javascript 时实际做了什么。(示例(

基本上,namespace只是创建一个对象,您可以在其中控制对象外部看到的内容。另一个属性是,如果有两个命名空间声明,并且在同一作用域上具有相同的名称,则会合并这些声明。 但归根结底,它只是在转译的 JavaScript 中实现为另一个变量。

Typescript 也有"真正的"模块,也称为外部模块。真正的模块意味着它们是隔离的,你需要某种机制在运行时加载它们。它可以是webpack或browserify,如果你的代码要在node.js中运行,它可以require函数,可能是reuqre.js库,但你需要一些东西。

任何具有顶级exportimport语句的文件都是模块。(命名空间内的导出不是顶级的!

因此,我们有两个选择: 1. 文件不是模块。 2. 文件是一个模块。

如果文件不是模块,则文件中声明的每个变量/类型都在全局范围内声明。

如果文件是模块,则每个变量/类型的范围都只限于该文件。

因此,一旦您添加:import { EventObjectInput } from 'fullcalendar/src/types/input-types';您将SearchMain.ts变成了外部模块。现在,SearchMain.ts中的命名空间MyProduct.Search是隔离的,在不同的范围内定义,然后是CarType.ts中定义的范围。所以你得到了你的错误。


TL;DR - 你能做什么?

混合内部模块和外部模块非常烦人。选一个。 强烈建议仅使用外部模块。不要使用命名空间,只使用导入和导出语句。迁移代码可能需要一段时间,但这是值得的。

另一种选择是继续使用namespace.不要importEventObjectInput.使其在其他命名空间上可用。但同样,不建议这样做。


有关打字稿文档中的更多信息

相关堆栈溢出答案

最新更新