【问题标题】:Typescript full-qualify namespace vs import what is the differenceTypescript full-qualify namespace vs import 有什么区别
【发布时间】:2019-12-03 17:09:07
【问题描述】:

您好,我在理解 Typescript 中的命名空间时遇到了一些问题... 这有什么区别:

export class FileBrowser {
    ...
    attached() {
        let elem = $("#file-manager");
        elem.dxFileManager({
            name: "fileManager",
            fileProvider: new DevExpress.fileProvider.RemoteFileProvider({
            })           
        });
    }
}

还有这个:

import RemoteFileProvider from 'devextreme/ui/file_manager/file_provider/remote';

export class FileBrowser {
    ...
    attached() {
        let elem = $("#file-manager");
        elem.dxFileManager({
            name: "fileManager",
            fileProvider: new RemoteFileProvider({                
            })           
        });
    }
}

所以在第一个(编译但不工作!)我用完全限定的命名空间名称指定RemoteFileProvider,而不导入它。在第二个(有效)中,我使用 import 然后引用 RemoteFileProvider 而没有完全限定它。

第一个代码确实编译没有问题,但在运行时抛出:

Uncaught (in promise) TypeError: Cannot read property 'RemoteFileProvider' of undefined

虽然第二个完美无缺。

更新 声明是:

declare module DevExpress {...}
declare module DevExpress.fileProvider {
    ...
    export class RemoteFileProvider extends FileProvider {
        ...
    }
}

【问题讨论】:

    标签: typescript module namespaces


    【解决方案1】:

    第一个示例假设您已经声明了一个全局命名空间,例如:

    namespace DevExpress {
        export namespace fileProvider {
            export class RemoteFileProvider {
                constructor(someProp: {}) {}
            }
        }
    }
    

    这个命名空间嵌入在一个脚本文件中(不是带有import/export的模块),在global JS范围内可用,可以直接使用(不必是imported)。您也可以在前面加上windowglobalThis 来访问RemoteFileProvider

    new window.DevExpress.fileProvider.RemoteFileProvider(/*your args*/)
    // or
    new globalThis.DevExpress.fileProvider.RemoteFileProvider(/*your args*/)           
    

    在第二个示例中,RemoteFileProvider 是模块remote 的默认export 成员,其绝对路径为'devextreme/ui/file_manager/file_provider/remote'

    export default class RemoteFileProvider {
        constructor(someProp: {}) {}
    }
    

    第一个代码确实编译没有问题,但在运行时抛出 [...] 而第二个代码完美运行。

    听起来您的命名空间定义存在缺陷(请参阅上面的命名空间作为正确示例),或者您错误地将 RemoteFileProvider 分配给全局范围。这也可能是一个提示,您已经声明了环境命名空间 declare namespace DevExpress(或类似名称),因此没有编译器声明的运行时等效代码。

    【讨论】:

    • 源不是我的所以没有变化。如果您可以看一下,我已经用附加信息(模块声明)更新了这个问题。似乎这些是模块而不是名称空间。这就是为什么它们在用作命名空间时不起作用的原因。但是为什么 VS 代码没有报告这个问题呢?
    • 哦,那是一些旧代码。 declare module DevExpress(注意:没有引号!)在 TS 1.5 之前被称为内部模块,如果我没记错的话,它与 TS1 中引入的 namespace 构造完全相同。 5+,用到现在。您的示例的精髓是:它们是命名空间,但它们是环境的(即没有实现,由 declare 关键字标记)。因此,如果其他地方没有实现,很明显会出现运行时错误。模块可以工作,因为'devextreme/ui/file_manager/file_provider/remote' 中可能有一个实现。
    • PS:如果您想了解更多关于这些内部模块的信息:herehere
    猜你喜欢
    • 2020-12-14
    • 2020-01-09
    • 1970-01-01
    • 1970-01-01
    • 2019-02-19
    • 2019-03-20
    • 1970-01-01
    • 2017-06-15
    • 2011-05-23
    相关资源
    最近更新 更多