如何导入***元素是非导出命名空间的 Typescript 类型定义文件?

Posted

技术标签:

【中文标题】如何导入***元素是非导出命名空间的 Typescript 类型定义文件?【英文标题】:How do you import a Typescript type definition file whose top level element is a non-exported namespace? 【发布时间】:2018-05-29 06:59:46 【问题描述】:

我正在尝试使用@types/googlemaps 类型定义文件。

代码看起来像

declare namespace google.maps 
    /***** Map *****/
    export class Map extends MVCObject 
        constructor(mapDiv: Element|null, opts?: MapOptions);
        fitBounds(bounds: LatLngBounds|LatLngBoundsLiteral): void;
        ...
        ...
        overlayMapTypes: MVCArray<MapType>;
    

    export interface MapOptions 
        backgroundColor?: string;
        disableDoubleClickZoom?: boolean;
        draggable?: boolean;
        ...

当我尝试在我的项目中使用这种类型定义时,就像这样

import * as google from 'googlemaps';

我得到一个编译错误说

Error:(2, 25) TS2306:File 'C:/Users/CodyB/musicappproj/src/node_modules/@types/googlemaps/index.d.ts' is not a module.

为什么它不认为这个类型定义文件是一个模块? 我用错了吗?定义文件错了吗?

【问题讨论】:

typescriptlang.org/docs/handbook/declaration-files/… 它必须是全局声明而不是模块.. 尝试使用 google.maps.Map.. 如果这不起作用,请尝试将 /// &lt;reference types="google" /&gt; 放在文件顶部 我在尝试使用@types/jest 定义的类型来输入 testdouble-jest 库时也遇到了这个问题。我尝试在定义文件(testdouble-jest.d.ts)中添加 /// 指令以及所有导入方式,但它似乎总是解决任何问题。有什么想法可以继续吗? 在单独的问题中添加了更多详细信息:***.com/questions/55961831/… 【参考方案1】:

为什么它不认为这个类型定义文件是一个模块?

编译器不会将此类型定义文件视为 ECMA6 模块,因为该文件缺少***导出/导入。相反,该文件将其导出嵌套/隐藏在 namespace 中并且不导出命名空间。结果,命名空间成为全局范围的一部分,而文件没有成为模块。

一个文件只有在它具有***导入或导出时才是一个模块。在下面的代码中,foo.tsbar.ts 都是模块,但 baz.ts 不是,因为它缺少*** importexport 语句。

// foo.ts
console.log('foo');
export 

// bar.ts
import * as foo from './foo';
console.log('bar');

// baz.ts
console.log('baz');

// index.ts
import * as foo from './foo';
import * as bar from './bar';
import * as baz from './baz'; // File 'c:/dev/temp/baz.ts' is not a module.ts(2306)

我用错了吗?

是的。您将文件视为一个模块 - 它不是。另一种方法是通过它定义的全局命名空间访问它的成员。这里有两种方法:

一种是像这样“点入”命名空间:

const div1 = new htmlDivElement();
const map1 = new google.maps.Map(div1);

另一种是像这样使用解构:

const  Map  = google.maps;
const div2 = new HTMLDivElement();
const map2 = new Map(div2);

定义文件错了吗?

没有。它采用了一种有效的方法,尽管对于浏览器(例如 Firefox)应用程序来说,这种方法可能比 NodeJS 应用程序更传统。

另见:

https://www.typescriptlang.org/docs/handbook/namespaces.html

https://www.typescriptlang.org/docs/handbook/namespaces-and-modules.html

【讨论】:

以上是关于如何导入***元素是非导出命名空间的 Typescript 类型定义文件?的主要内容,如果未能解决你的问题,请参考以下文章

ExcelPackage导入导出,命名空间一定要是EPPlus

如何使用 Nokogiri Builder 创建具有命名空间根元素的 XML 文档

我想把WinForm上的内容导出为PDF文档,用C# VS2010 需要引用哪些 dll ,导入哪些命名空间?具体怎么做呢?

ES6 - 如何导入和别名命名导出的成员?

Javascript命名空间 - 如何根据命名导出函数范围内定义的函数和变量?

Confluence 6 恢复一个空间的问题解决