【问题标题】:Importing a module breaks local types with Property does not exist on type导入模块会破坏类型上不存在属性的本地类型
【发布时间】:2023-03-09 19:14:01
【问题描述】:

我有一个名为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 与我的代码一起使用?

【问题讨论】:

    标签: typescript


    【解决方案1】:

    这是一个令人困惑的:

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

    我建议查看 Typescript Playground,以了解 namespace 关键字在转换为 javascript 时的实际作用。 (example)

    基本上,namespace 只是创建一个对象,您可以在其中控制在对象之外看到的内容。另一个属性是,如果您有两个名称空间声明,并且在同一范围内具有相同的名称,则声明将被合并。 但归根结底,它只是作为转换后的 javascript 中的另一个变量实现的。

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

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

    所以,我们有两个选择: 1. 文件不是模块。 2. 文件就是模块。

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

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

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


    TL;DR - 你能做什么?

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

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


    for more info from Typescript documentation

    related stack overflow answer

    【讨论】:

      猜你喜欢
      • 2020-12-24
      • 1970-01-01
      • 1970-01-01
      • 2020-10-28
      • 2017-01-11
      • 2020-05-01
      • 1970-01-01
      • 1970-01-01
      • 2021-11-30
      相关资源
      最近更新 更多